Root/
Source at commit 654fa4606ec498505bac64ceb8c5ccffb18da55d created 10 years 7 months ago. By Lars-Peter Clausen, ASoC: jz4740: Use the generic dmaengine PCM driver | |
---|---|
1 | /* |
2 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the |
6 | * Free Software Foundation; either version 2 of the License, or (at your |
7 | * option) any later version. |
8 | * |
9 | * You should have received a copy of the GNU General Public License along |
10 | * with this program; if not, write to the Free Software Foundation, Inc., |
11 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
12 | * |
13 | */ |
14 | |
15 | #include <linux/init.h> |
16 | #include <linux/io.h> |
17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> |
19 | #include <linux/platform_device.h> |
20 | #include <linux/slab.h> |
21 | |
22 | #include <linux/clk.h> |
23 | #include <linux/delay.h> |
24 | |
25 | #include <linux/dma-mapping.h> |
26 | |
27 | #include <sound/core.h> |
28 | #include <sound/pcm.h> |
29 | #include <sound/pcm_params.h> |
30 | #include <sound/soc.h> |
31 | #include <sound/initval.h> |
32 | #include <sound/dmaengine_pcm.h> |
33 | |
34 | #include <asm/mach-jz4740/dma.h> |
35 | |
36 | #include "jz4740-i2s.h" |
37 | |
38 | |
39 | #define JZ_REG_AIC_CONF 0x00 |
40 | #define JZ_REG_AIC_CTRL 0x04 |
41 | #define JZ_REG_AIC_I2S_FMT 0x10 |
42 | #define JZ_REG_AIC_FIFO_STATUS 0x14 |
43 | #define JZ_REG_AIC_I2S_STATUS 0x1c |
44 | #define JZ_REG_AIC_CLK_DIV 0x30 |
45 | #define JZ_REG_AIC_FIFO 0x34 |
46 | |
47 | #define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12) |
48 | #define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf << 8) |
49 | #define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6) |
50 | #define JZ_AIC_CONF_INTERNAL_CODEC BIT(5) |
51 | #define JZ_AIC_CONF_I2S BIT(4) |
52 | #define JZ_AIC_CONF_RESET BIT(3) |
53 | #define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2) |
54 | #define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1) |
55 | #define JZ_AIC_CONF_ENABLE BIT(0) |
56 | |
57 | #define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12 |
58 | #define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8 |
59 | |
60 | #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19) |
61 | #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16) |
62 | #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15) |
63 | #define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14) |
64 | #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11) |
65 | #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10) |
66 | #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9) |
67 | #define JZ_AIC_CTRL_FLUSH BIT(8) |
68 | #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6) |
69 | #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5) |
70 | #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4) |
71 | #define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3) |
72 | #define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2) |
73 | #define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1) |
74 | #define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0) |
75 | |
76 | #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19 |
77 | #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16 |
78 | |
79 | #define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12) |
80 | #define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4) |
81 | #define JZ_AIC_I2S_FMT_MSB BIT(0) |
82 | |
83 | #define JZ_AIC_I2S_STATUS_BUSY BIT(2) |
84 | |
85 | #define JZ_AIC_CLK_DIV_MASK 0xf |
86 | |
87 | struct jz4740_i2s { |
88 | struct resource *mem; |
89 | void __iomem *base; |
90 | dma_addr_t phys_base; |
91 | |
92 | struct clk *clk_aic; |
93 | struct clk *clk_i2s; |
94 | |
95 | struct snd_dmaengine_dai_dma_data playback_dma_data; |
96 | struct snd_dmaengine_dai_dma_data capture_dma_data; |
97 | }; |
98 | |
99 | static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, |
100 | unsigned int reg) |
101 | { |
102 | return readl(i2s->base + reg); |
103 | } |
104 | |
105 | static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s, |
106 | unsigned int reg, uint32_t value) |
107 | { |
108 | writel(value, i2s->base + reg); |
109 | } |
110 | |
111 | static int jz4740_i2s_startup(struct snd_pcm_substream *substream, |
112 | struct snd_soc_dai *dai) |
113 | { |
114 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
115 | uint32_t conf, ctrl; |
116 | |
117 | if (dai->active) |
118 | return 0; |
119 | |
120 | ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL); |
121 | ctrl |= JZ_AIC_CTRL_FLUSH; |
122 | jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); |
123 | |
124 | clk_prepare_enable(i2s->clk_i2s); |
125 | |
126 | conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); |
127 | conf |= JZ_AIC_CONF_ENABLE; |
128 | jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); |
129 | |
130 | return 0; |
131 | } |
132 | |
133 | static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, |
134 | struct snd_soc_dai *dai) |
135 | { |
136 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
137 | uint32_t conf; |
138 | |
139 | if (dai->active) |
140 | return; |
141 | |
142 | conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); |
143 | conf &= ~JZ_AIC_CONF_ENABLE; |
144 | jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); |
145 | |
146 | clk_disable_unprepare(i2s->clk_i2s); |
147 | } |
148 | |
149 | static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd, |
150 | struct snd_soc_dai *dai) |
151 | { |
152 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
153 | |
154 | uint32_t ctrl; |
155 | uint32_t mask; |
156 | |
157 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
158 | mask = JZ_AIC_CTRL_ENABLE_PLAYBACK | JZ_AIC_CTRL_ENABLE_TX_DMA; |
159 | else |
160 | mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA; |
161 | |
162 | ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL); |
163 | |
164 | switch (cmd) { |
165 | case SNDRV_PCM_TRIGGER_START: |
166 | case SNDRV_PCM_TRIGGER_RESUME: |
167 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
168 | ctrl |= mask; |
169 | break; |
170 | case SNDRV_PCM_TRIGGER_STOP: |
171 | case SNDRV_PCM_TRIGGER_SUSPEND: |
172 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
173 | ctrl &= ~mask; |
174 | break; |
175 | default: |
176 | return -EINVAL; |
177 | } |
178 | |
179 | jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); |
180 | |
181 | return 0; |
182 | } |
183 | |
184 | static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
185 | { |
186 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
187 | |
188 | uint32_t format = 0; |
189 | uint32_t conf; |
190 | |
191 | conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); |
192 | |
193 | conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER); |
194 | |
195 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
196 | case SND_SOC_DAIFMT_CBS_CFS: |
197 | conf |= JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER; |
198 | format |= JZ_AIC_I2S_FMT_ENABLE_SYS_CLK; |
199 | break; |
200 | case SND_SOC_DAIFMT_CBM_CFS: |
201 | conf |= JZ_AIC_CONF_SYNC_CLK_MASTER; |
202 | break; |
203 | case SND_SOC_DAIFMT_CBS_CFM: |
204 | conf |= JZ_AIC_CONF_BIT_CLK_MASTER; |
205 | break; |
206 | case SND_SOC_DAIFMT_CBM_CFM: |
207 | break; |
208 | default: |
209 | return -EINVAL; |
210 | } |
211 | |
212 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
213 | case SND_SOC_DAIFMT_MSB: |
214 | format |= JZ_AIC_I2S_FMT_MSB; |
215 | break; |
216 | case SND_SOC_DAIFMT_I2S: |
217 | break; |
218 | default: |
219 | return -EINVAL; |
220 | } |
221 | |
222 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
223 | case SND_SOC_DAIFMT_NB_NF: |
224 | break; |
225 | default: |
226 | return -EINVAL; |
227 | } |
228 | |
229 | jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); |
230 | jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format); |
231 | |
232 | return 0; |
233 | } |
234 | |
235 | static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, |
236 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
237 | { |
238 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
239 | unsigned int sample_size; |
240 | uint32_t ctrl; |
241 | |
242 | ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL); |
243 | |
244 | switch (params_format(params)) { |
245 | case SNDRV_PCM_FORMAT_S8: |
246 | sample_size = 0; |
247 | break; |
248 | case SNDRV_PCM_FORMAT_S16: |
249 | sample_size = 1; |
250 | break; |
251 | default: |
252 | return -EINVAL; |
253 | } |
254 | |
255 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
256 | ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK; |
257 | ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET; |
258 | if (params_channels(params) == 1) |
259 | ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO; |
260 | else |
261 | ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO; |
262 | } else { |
263 | ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK; |
264 | ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; |
265 | } |
266 | |
267 | jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); |
268 | |
269 | return 0; |
270 | } |
271 | |
272 | static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, |
273 | unsigned int freq, int dir) |
274 | { |
275 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
276 | struct clk *parent; |
277 | int ret = 0; |
278 | |
279 | switch (clk_id) { |
280 | case JZ4740_I2S_CLKSRC_EXT: |
281 | parent = clk_get(NULL, "ext"); |
282 | clk_set_parent(i2s->clk_i2s, parent); |
283 | break; |
284 | case JZ4740_I2S_CLKSRC_PLL: |
285 | parent = clk_get(NULL, "pll half"); |
286 | clk_set_parent(i2s->clk_i2s, parent); |
287 | ret = clk_set_rate(i2s->clk_i2s, freq); |
288 | break; |
289 | default: |
290 | return -EINVAL; |
291 | } |
292 | clk_put(parent); |
293 | |
294 | return ret; |
295 | } |
296 | |
297 | static int jz4740_i2s_suspend(struct snd_soc_dai *dai) |
298 | { |
299 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
300 | uint32_t conf; |
301 | |
302 | if (dai->active) { |
303 | conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); |
304 | conf &= ~JZ_AIC_CONF_ENABLE; |
305 | jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); |
306 | |
307 | clk_disable_unprepare(i2s->clk_i2s); |
308 | } |
309 | |
310 | clk_disable_unprepare(i2s->clk_aic); |
311 | |
312 | return 0; |
313 | } |
314 | |
315 | static int jz4740_i2s_resume(struct snd_soc_dai *dai) |
316 | { |
317 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
318 | uint32_t conf; |
319 | |
320 | clk_prepare_enable(i2s->clk_aic); |
321 | |
322 | if (dai->active) { |
323 | clk_prepare_enable(i2s->clk_i2s); |
324 | |
325 | conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); |
326 | conf |= JZ_AIC_CONF_ENABLE; |
327 | jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); |
328 | } |
329 | |
330 | return 0; |
331 | } |
332 | |
333 | static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s) |
334 | { |
335 | struct snd_dmaengine_dai_dma_data *dma_data; |
336 | |
337 | /* Playback */ |
338 | dma_data = &i2s->playback_dma_data; |
339 | dma_data->maxburst = 16; |
340 | dma_data->slave_id = JZ4740_DMA_TYPE_AIC_TRANSMIT; |
341 | dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO; |
342 | |
343 | /* Capture */ |
344 | dma_data = &i2s->capture_dma_data; |
345 | dma_data->maxburst = 16; |
346 | dma_data->slave_id = JZ4740_DMA_TYPE_AIC_RECEIVE; |
347 | dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO; |
348 | } |
349 | |
350 | static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) |
351 | { |
352 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
353 | uint32_t conf; |
354 | |
355 | clk_prepare_enable(i2s->clk_aic); |
356 | |
357 | jz4740_i2c_init_pcm_config(i2s); |
358 | dai->playback_dma_data = &i2s->playback_dma_data; |
359 | dai->capture_dma_data = &i2s->capture_dma_data; |
360 | |
361 | conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | |
362 | (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | |
363 | JZ_AIC_CONF_OVERFLOW_PLAY_LAST | |
364 | JZ_AIC_CONF_I2S | |
365 | JZ_AIC_CONF_INTERNAL_CODEC; |
366 | |
367 | jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET); |
368 | jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); |
369 | |
370 | return 0; |
371 | } |
372 | |
373 | static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai) |
374 | { |
375 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
376 | |
377 | clk_disable_unprepare(i2s->clk_aic); |
378 | return 0; |
379 | } |
380 | |
381 | static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = { |
382 | .startup = jz4740_i2s_startup, |
383 | .shutdown = jz4740_i2s_shutdown, |
384 | .trigger = jz4740_i2s_trigger, |
385 | .hw_params = jz4740_i2s_hw_params, |
386 | .set_fmt = jz4740_i2s_set_fmt, |
387 | .set_sysclk = jz4740_i2s_set_sysclk, |
388 | }; |
389 | |
390 | #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ |
391 | SNDRV_PCM_FMTBIT_S16_LE) |
392 | |
393 | static struct snd_soc_dai_driver jz4740_i2s_dai = { |
394 | .probe = jz4740_i2s_dai_probe, |
395 | .remove = jz4740_i2s_dai_remove, |
396 | .playback = { |
397 | .channels_min = 1, |
398 | .channels_max = 2, |
399 | .rates = SNDRV_PCM_RATE_8000_48000, |
400 | .formats = JZ4740_I2S_FMTS, |
401 | }, |
402 | .capture = { |
403 | .channels_min = 2, |
404 | .channels_max = 2, |
405 | .rates = SNDRV_PCM_RATE_8000_48000, |
406 | .formats = JZ4740_I2S_FMTS, |
407 | }, |
408 | .symmetric_rates = 1, |
409 | .ops = &jz4740_i2s_dai_ops, |
410 | .suspend = jz4740_i2s_suspend, |
411 | .resume = jz4740_i2s_resume, |
412 | }; |
413 | |
414 | static const struct snd_soc_component_driver jz4740_i2s_component = { |
415 | .name = "jz4740-i2s", |
416 | }; |
417 | |
418 | static int jz4740_i2s_dev_probe(struct platform_device *pdev) |
419 | { |
420 | struct jz4740_i2s *i2s; |
421 | int ret; |
422 | |
423 | i2s = kzalloc(sizeof(*i2s), GFP_KERNEL); |
424 | |
425 | if (!i2s) |
426 | return -ENOMEM; |
427 | |
428 | i2s->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
429 | if (!i2s->mem) { |
430 | ret = -ENOENT; |
431 | goto err_free; |
432 | } |
433 | |
434 | i2s->mem = request_mem_region(i2s->mem->start, resource_size(i2s->mem), |
435 | pdev->name); |
436 | if (!i2s->mem) { |
437 | ret = -EBUSY; |
438 | goto err_free; |
439 | } |
440 | |
441 | i2s->base = ioremap_nocache(i2s->mem->start, resource_size(i2s->mem)); |
442 | if (!i2s->base) { |
443 | ret = -EBUSY; |
444 | goto err_release_mem_region; |
445 | } |
446 | |
447 | i2s->phys_base = i2s->mem->start; |
448 | |
449 | i2s->clk_aic = clk_get(&pdev->dev, "aic"); |
450 | if (IS_ERR(i2s->clk_aic)) { |
451 | ret = PTR_ERR(i2s->clk_aic); |
452 | goto err_iounmap; |
453 | } |
454 | |
455 | i2s->clk_i2s = clk_get(&pdev->dev, "i2s"); |
456 | if (IS_ERR(i2s->clk_i2s)) { |
457 | ret = PTR_ERR(i2s->clk_i2s); |
458 | goto err_clk_put_aic; |
459 | } |
460 | |
461 | platform_set_drvdata(pdev, i2s); |
462 | ret = snd_soc_register_component(&pdev->dev, &jz4740_i2s_component, |
463 | &jz4740_i2s_dai, 1); |
464 | |
465 | if (ret) { |
466 | dev_err(&pdev->dev, "Failed to register DAI\n"); |
467 | goto err_clk_put_i2s; |
468 | } |
469 | |
470 | return 0; |
471 | |
472 | err_clk_put_i2s: |
473 | clk_put(i2s->clk_i2s); |
474 | err_clk_put_aic: |
475 | clk_put(i2s->clk_aic); |
476 | err_iounmap: |
477 | iounmap(i2s->base); |
478 | err_release_mem_region: |
479 | release_mem_region(i2s->mem->start, resource_size(i2s->mem)); |
480 | err_free: |
481 | kfree(i2s); |
482 | |
483 | return ret; |
484 | } |
485 | |
486 | static int jz4740_i2s_dev_remove(struct platform_device *pdev) |
487 | { |
488 | struct jz4740_i2s *i2s = platform_get_drvdata(pdev); |
489 | |
490 | snd_soc_unregister_component(&pdev->dev); |
491 | |
492 | clk_put(i2s->clk_i2s); |
493 | clk_put(i2s->clk_aic); |
494 | |
495 | iounmap(i2s->base); |
496 | release_mem_region(i2s->mem->start, resource_size(i2s->mem)); |
497 | |
498 | kfree(i2s); |
499 | |
500 | return 0; |
501 | } |
502 | |
503 | static struct platform_driver jz4740_i2s_driver = { |
504 | .probe = jz4740_i2s_dev_probe, |
505 | .remove = jz4740_i2s_dev_remove, |
506 | .driver = { |
507 | .name = "jz4740-i2s", |
508 | .owner = THIS_MODULE, |
509 | }, |
510 | }; |
511 | |
512 | module_platform_driver(jz4740_i2s_driver); |
513 | |
514 | MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>"); |
515 | MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver"); |
516 | MODULE_LICENSE("GPL"); |
517 | MODULE_ALIAS("platform:jz4740-i2s"); |
518 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9