kirkwood-i2s.c (7bcc1ec07748cae3552dc9b46701c117926c8923) | kirkwood-i2s.c (b25b5aa06667b01fee8fe2648d4ea9db32c87d1a) |
---|---|
1/* 2 * kirkwood-i2s.c 3 * 4 * (c) 2010 Arnaud Patard <apatard@mandriva.com> 5 * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the --- 85 unchanged lines hidden (view full) --- 94 /* wait for dco locked */ 95 do { 96 cpu_relax(); 97 value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); 98 value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK; 99 } while (value == 0); 100} 101 | 1/* 2 * kirkwood-i2s.c 3 * 4 * (c) 2010 Arnaud Patard <apatard@mandriva.com> 5 * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the --- 85 unchanged lines hidden (view full) --- 94 /* wait for dco locked */ 95 do { 96 cpu_relax(); 97 value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); 98 value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK; 99 } while (value == 0); 100} 101 |
102static void kirkwood_set_rate(struct snd_soc_dai *dai, 103 struct kirkwood_dma_data *priv, unsigned long rate) 104{ 105 uint32_t clks_ctrl; 106 107 if (rate == 44100 || rate == 48000 || rate == 96000) { 108 /* use internal dco for supported rates */ 109 dev_dbg(dai->dev, "%s: dco set rate = %lu\n", 110 __func__, rate); 111 kirkwood_set_dco(priv->io, rate); 112 113 clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO; 114 } else if (!IS_ERR(priv->extclk)) { 115 /* use optional external clk for other rates */ 116 dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n", 117 __func__, rate, 256 * rate); 118 clk_set_rate(priv->extclk, 256 * rate); 119 120 clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK; 121 } 122 writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL); 123} 124 |
|
102static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, 103 struct snd_soc_dai *dai) 104{ 105 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); 106 107 snd_soc_dai_set_dma_data(dai, substream, priv); 108 return 0; 109} 110 111static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, 112 struct snd_pcm_hw_params *params, 113 struct snd_soc_dai *dai) 114{ 115 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); | 125static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, 126 struct snd_soc_dai *dai) 127{ 128 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); 129 130 snd_soc_dai_set_dma_data(dai, substream, priv); 131 return 0; 132} 133 134static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, 135 struct snd_pcm_hw_params *params, 136 struct snd_soc_dai *dai) 137{ 138 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); |
116 unsigned int i2s_reg, reg; 117 unsigned long i2s_value, value; | 139 uint32_t ctl_play, ctl_rec; 140 unsigned int i2s_reg; 141 unsigned long i2s_value; |
118 119 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 120 i2s_reg = KIRKWOOD_I2S_PLAYCTL; | 142 143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 144 i2s_reg = KIRKWOOD_I2S_PLAYCTL; |
121 reg = KIRKWOOD_PLAYCTL; | |
122 } else { 123 i2s_reg = KIRKWOOD_I2S_RECCTL; | 145 } else { 146 i2s_reg = KIRKWOOD_I2S_RECCTL; |
124 reg = KIRKWOOD_RECCTL; | |
125 } 126 | 147 } 148 |
127 /* set dco conf */ 128 kirkwood_set_dco(priv->io, params_rate(params)); | 149 kirkwood_set_rate(dai, priv, params_rate(params)); |
129 130 i2s_value = readl(priv->io+i2s_reg); 131 i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; 132 | 150 151 i2s_value = readl(priv->io+i2s_reg); 152 i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; 153 |
133 value = readl(priv->io+reg); 134 value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK; 135 | |
136 /* 137 * Size settings in play/rec i2s control regs and play/rec control 138 * regs must be the same. 139 */ 140 switch (params_format(params)) { 141 case SNDRV_PCM_FORMAT_S16_LE: 142 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; | 154 /* 155 * Size settings in play/rec i2s control regs and play/rec control 156 * regs must be the same. 157 */ 158 switch (params_format(params)) { 159 case SNDRV_PCM_FORMAT_S16_LE: 160 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; |
143 value |= KIRKWOOD_PLAYCTL_SIZE_16_C; | 161 ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C | 162 KIRKWOOD_PLAYCTL_I2S_EN; 163 ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C | 164 KIRKWOOD_RECCTL_I2S_EN; |
144 break; 145 /* 146 * doesn't work... S20_3LE != kirkwood 20bit format ? 147 * 148 case SNDRV_PCM_FORMAT_S20_3LE: 149 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; | 165 break; 166 /* 167 * doesn't work... S20_3LE != kirkwood 20bit format ? 168 * 169 case SNDRV_PCM_FORMAT_S20_3LE: 170 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; |
150 value |= KIRKWOOD_PLAYCTL_SIZE_20; | 171 ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 | 172 KIRKWOOD_PLAYCTL_I2S_EN; 173 ctl_rec = KIRKWOOD_RECCTL_SIZE_20 | 174 KIRKWOOD_RECCTL_I2S_EN; |
151 break; 152 */ 153 case SNDRV_PCM_FORMAT_S24_LE: 154 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; | 175 break; 176 */ 177 case SNDRV_PCM_FORMAT_S24_LE: 178 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; |
155 value |= KIRKWOOD_PLAYCTL_SIZE_24; | 179 ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 | 180 KIRKWOOD_PLAYCTL_I2S_EN; 181 ctl_rec = KIRKWOOD_RECCTL_SIZE_24 | 182 KIRKWOOD_RECCTL_I2S_EN; |
156 break; 157 case SNDRV_PCM_FORMAT_S32_LE: 158 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; | 183 break; 184 case SNDRV_PCM_FORMAT_S32_LE: 185 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; |
159 value |= KIRKWOOD_PLAYCTL_SIZE_32; | 186 ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 | 187 KIRKWOOD_PLAYCTL_I2S_EN; 188 ctl_rec = KIRKWOOD_RECCTL_SIZE_32 | 189 KIRKWOOD_RECCTL_I2S_EN; |
160 break; 161 default: 162 return -EINVAL; 163 } 164 165 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 190 break; 191 default: 192 return -EINVAL; 193 } 194 195 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
166 value &= ~KIRKWOOD_PLAYCTL_MONO_MASK; | |
167 if (params_channels(params) == 1) | 196 if (params_channels(params) == 1) |
168 value |= KIRKWOOD_PLAYCTL_MONO_BOTH; | 197 ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH; |
169 else | 198 else |
170 value |= KIRKWOOD_PLAYCTL_MONO_OFF; | 199 ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF; 200 201 priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK | 202 KIRKWOOD_PLAYCTL_I2S_EN | 203 KIRKWOOD_PLAYCTL_SPDIF_EN | 204 KIRKWOOD_PLAYCTL_SIZE_MASK); 205 priv->ctl_play |= ctl_play; 206 } else { 207 priv->ctl_rec &= ~KIRKWOOD_RECCTL_SIZE_MASK; 208 priv->ctl_rec |= ctl_rec; |
171 } 172 173 writel(i2s_value, priv->io+i2s_reg); | 209 } 210 211 writel(i2s_value, priv->io+i2s_reg); |
174 writel(value, priv->io+reg); | |
175 176 return 0; 177} 178 179static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, 180 int cmd, struct snd_soc_dai *dai) 181{ 182 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); --- 17 unchanged lines hidden (view full) --- 200 201 if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY) 202 dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", 203 ctl); 204 } 205 206 switch (cmd) { 207 case SNDRV_PCM_TRIGGER_START: | 212 213 return 0; 214} 215 216static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, 217 int cmd, struct snd_soc_dai *dai) 218{ 219 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); --- 17 unchanged lines hidden (view full) --- 237 238 if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY) 239 dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", 240 ctl); 241 } 242 243 switch (cmd) { 244 case SNDRV_PCM_TRIGGER_START: |
245 /* configure */ 246 ctl = priv->ctl_play; 247 value = ctl & ~(KIRKWOOD_PLAYCTL_I2S_EN | 248 KIRKWOOD_PLAYCTL_SPDIF_EN); 249 writel(value, priv->io + KIRKWOOD_PLAYCTL); 250 251 /* enable interrupts */ |
|
208 value = readl(priv->io + KIRKWOOD_INT_MASK); 209 value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; 210 writel(value, priv->io + KIRKWOOD_INT_MASK); 211 | 252 value = readl(priv->io + KIRKWOOD_INT_MASK); 253 value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; 254 writel(value, priv->io + KIRKWOOD_INT_MASK); 255 |
212 /* configure audio & enable i2s playback */ 213 ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK; 214 ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE 215 | KIRKWOOD_PLAYCTL_SPDIF_EN); 216 217 if (priv->burst == 32) 218 ctl |= KIRKWOOD_PLAYCTL_BURST_32; 219 else 220 ctl |= KIRKWOOD_PLAYCTL_BURST_128; 221 ctl |= KIRKWOOD_PLAYCTL_I2S_EN; | 256 /* enable playback */ |
222 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 223 break; 224 225 case SNDRV_PCM_TRIGGER_STOP: 226 /* stop audio, disable interrupts */ 227 ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; 228 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 229 --- 24 unchanged lines hidden (view full) --- 254 255 return 0; 256} 257 258static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, 259 int cmd, struct snd_soc_dai *dai) 260{ 261 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); | 257 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 258 break; 259 260 case SNDRV_PCM_TRIGGER_STOP: 261 /* stop audio, disable interrupts */ 262 ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; 263 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 264 --- 24 unchanged lines hidden (view full) --- 289 290 return 0; 291} 292 293static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, 294 int cmd, struct snd_soc_dai *dai) 295{ 296 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); |
262 unsigned long value; | 297 uint32_t ctl, value; |
263 264 value = readl(priv->io + KIRKWOOD_RECCTL); 265 266 switch (cmd) { 267 case SNDRV_PCM_TRIGGER_START: | 298 299 value = readl(priv->io + KIRKWOOD_RECCTL); 300 301 switch (cmd) { 302 case SNDRV_PCM_TRIGGER_START: |
303 /* configure */ 304 ctl = priv->ctl_rec; 305 value = ctl & ~KIRKWOOD_RECCTL_I2S_EN; 306 writel(value, priv->io + KIRKWOOD_RECCTL); 307 308 /* enable interrupts */ |
|
268 value = readl(priv->io + KIRKWOOD_INT_MASK); 269 value |= KIRKWOOD_INT_CAUSE_REC_BYTES; 270 writel(value, priv->io + KIRKWOOD_INT_MASK); 271 | 309 value = readl(priv->io + KIRKWOOD_INT_MASK); 310 value |= KIRKWOOD_INT_CAUSE_REC_BYTES; 311 writel(value, priv->io + KIRKWOOD_INT_MASK); 312 |
272 /* configure audio & enable i2s record */ 273 value = readl(priv->io + KIRKWOOD_RECCTL); 274 value &= ~KIRKWOOD_RECCTL_BURST_MASK; 275 value &= ~KIRKWOOD_RECCTL_MONO; 276 value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE 277 | KIRKWOOD_RECCTL_SPDIF_EN); 278 279 if (priv->burst == 32) 280 value |= KIRKWOOD_RECCTL_BURST_32; 281 else 282 value |= KIRKWOOD_RECCTL_BURST_128; 283 value |= KIRKWOOD_RECCTL_I2S_EN; 284 285 writel(value, priv->io + KIRKWOOD_RECCTL); | 313 /* enable record */ 314 writel(ctl, priv->io + KIRKWOOD_RECCTL); |
286 break; 287 288 case SNDRV_PCM_TRIGGER_STOP: 289 /* stop audio, disable interrupts */ 290 value = readl(priv->io + KIRKWOOD_RECCTL); 291 value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE; 292 writel(value, priv->io + KIRKWOOD_RECCTL); 293 --- 90 unchanged lines hidden (view full) --- 384 385static struct snd_soc_dai_driver kirkwood_i2s_dai = { 386 .probe = kirkwood_i2s_probe, 387 .remove = kirkwood_i2s_remove, 388 .playback = { 389 .channels_min = 1, 390 .channels_max = 2, 391 .rates = KIRKWOOD_I2S_RATES, | 315 break; 316 317 case SNDRV_PCM_TRIGGER_STOP: 318 /* stop audio, disable interrupts */ 319 value = readl(priv->io + KIRKWOOD_RECCTL); 320 value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE; 321 writel(value, priv->io + KIRKWOOD_RECCTL); 322 --- 90 unchanged lines hidden (view full) --- 413 414static struct snd_soc_dai_driver kirkwood_i2s_dai = { 415 .probe = kirkwood_i2s_probe, 416 .remove = kirkwood_i2s_remove, 417 .playback = { 418 .channels_min = 1, 419 .channels_max = 2, 420 .rates = KIRKWOOD_I2S_RATES, |
392 .formats = KIRKWOOD_I2S_FORMATS,}, | 421 .formats = KIRKWOOD_I2S_FORMATS, 422 }, |
393 .capture = { 394 .channels_min = 1, 395 .channels_max = 2, 396 .rates = KIRKWOOD_I2S_RATES, | 423 .capture = { 424 .channels_min = 1, 425 .channels_max = 2, 426 .rates = KIRKWOOD_I2S_RATES, |
397 .formats = KIRKWOOD_I2S_FORMATS,}, | 427 .formats = KIRKWOOD_I2S_FORMATS, 428 }, |
398 .ops = &kirkwood_i2s_dai_ops, 399}; 400 | 429 .ops = &kirkwood_i2s_dai_ops, 430}; 431 |
401static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) | 432static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = { 433 .probe = kirkwood_i2s_probe, 434 .remove = kirkwood_i2s_remove, 435 .playback = { 436 .channels_min = 1, 437 .channels_max = 2, 438 .rates = SNDRV_PCM_RATE_8000_192000 | 439 SNDRV_PCM_RATE_CONTINUOUS | 440 SNDRV_PCM_RATE_KNOT, 441 .formats = KIRKWOOD_I2S_FORMATS, 442 }, 443 .capture = { 444 .channels_min = 1, 445 .channels_max = 2, 446 .rates = SNDRV_PCM_RATE_8000_192000 | 447 SNDRV_PCM_RATE_CONTINUOUS | 448 SNDRV_PCM_RATE_KNOT, 449 .formats = KIRKWOOD_I2S_FORMATS, 450 }, 451 .ops = &kirkwood_i2s_dai_ops, 452}; 453 454static int kirkwood_i2s_dev_probe(struct platform_device *pdev) |
402{ | 455{ |
403 struct resource *mem; 404 struct kirkwood_asoc_platform_data *data = 405 pdev->dev.platform_data; | 456 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; 457 struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; |
406 struct kirkwood_dma_data *priv; | 458 struct kirkwood_dma_data *priv; |
459 struct resource *mem; |
|
407 int err; 408 | 460 int err; 461 |
409 priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL); | 462 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
410 if (!priv) { 411 dev_err(&pdev->dev, "allocation failed\n"); | 463 if (!priv) { 464 dev_err(&pdev->dev, "allocation failed\n"); |
412 err = -ENOMEM; 413 goto error; | 465 return -ENOMEM; |
414 } 415 dev_set_drvdata(&pdev->dev, priv); 416 417 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 418 if (!mem) { 419 dev_err(&pdev->dev, "platform_get_resource failed\n"); | 466 } 467 dev_set_drvdata(&pdev->dev, priv); 468 469 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 470 if (!mem) { 471 dev_err(&pdev->dev, "platform_get_resource failed\n"); |
420 err = -ENXIO; 421 goto err_alloc; | 472 return -ENXIO; |
422 } 423 | 473 } 474 |
424 priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME); 425 if (!priv->mem) { 426 dev_err(&pdev->dev, "request_mem_region failed\n"); 427 err = -EBUSY; 428 goto err_alloc; 429 } | 475 priv->io = devm_ioremap_resource(&pdev->dev, mem); 476 if (IS_ERR(priv->io)) 477 return PTR_ERR(priv->io); |
430 | 478 |
431 priv->io = ioremap(priv->mem->start, SZ_16K); 432 if (!priv->io) { 433 dev_err(&pdev->dev, "ioremap failed\n"); 434 err = -ENOMEM; 435 goto err_iomem; 436 } 437 | |
438 priv->irq = platform_get_irq(pdev, 0); 439 if (priv->irq <= 0) { 440 dev_err(&pdev->dev, "platform_get_irq failed\n"); | 479 priv->irq = platform_get_irq(pdev, 0); 480 if (priv->irq <= 0) { 481 dev_err(&pdev->dev, "platform_get_irq failed\n"); |
441 err = -ENXIO; 442 goto err_ioremap; | 482 return -ENXIO; |
443 } 444 445 if (!data) { 446 dev_err(&pdev->dev, "no platform data ?!\n"); | 483 } 484 485 if (!data) { 486 dev_err(&pdev->dev, "no platform data ?!\n"); |
447 err = -EINVAL; 448 goto err_ioremap; | 487 return -EINVAL; |
449 } 450 451 priv->burst = data->burst; 452 | 488 } 489 490 priv->burst = data->burst; 491 |
453 priv->clk = clk_get(&pdev->dev, NULL); | 492 priv->clk = devm_clk_get(&pdev->dev, NULL); |
454 if (IS_ERR(priv->clk)) { 455 dev_err(&pdev->dev, "no clock\n"); | 493 if (IS_ERR(priv->clk)) { 494 dev_err(&pdev->dev, "no clock\n"); |
456 err = PTR_ERR(priv->clk); 457 goto err_ioremap; | 495 return PTR_ERR(priv->clk); |
458 } | 496 } |
459 clk_prepare_enable(priv->clk); | |
460 | 497 |
461 err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); | 498 err = clk_prepare_enable(priv->clk); 499 if (err < 0) 500 return err; 501 502 priv->extclk = clk_get(&pdev->dev, "extclk"); 503 if (!IS_ERR(priv->extclk)) { 504 if (priv->extclk == priv->clk) { 505 clk_put(priv->extclk); 506 priv->extclk = ERR_PTR(-EINVAL); 507 } else { 508 dev_info(&pdev->dev, "found external clock\n"); 509 clk_prepare_enable(priv->extclk); 510 soc_dai = &kirkwood_i2s_dai_extclk; 511 } 512 } 513 514 /* Some sensible defaults - this reflects the powerup values */ 515 priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; 516 priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; 517 518 /* Select the burst size */ 519 if (data->burst == 32) { 520 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; 521 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; 522 } else { 523 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128; 524 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; 525 } 526 527 err = snd_soc_register_dai(&pdev->dev, soc_dai); |
462 if (!err) 463 return 0; 464 dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); 465 | 528 if (!err) 529 return 0; 530 dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); 531 |
532 if (!IS_ERR(priv->extclk)) { 533 clk_disable_unprepare(priv->extclk); 534 clk_put(priv->extclk); 535 } |
|
466 clk_disable_unprepare(priv->clk); | 536 clk_disable_unprepare(priv->clk); |
467 clk_put(priv->clk); | |
468 | 537 |
469err_ioremap: 470 iounmap(priv->io); 471err_iomem: 472 release_mem_region(priv->mem->start, SZ_16K); 473err_alloc: 474 kfree(priv); 475error: | |
476 return err; 477} 478 | 538 return err; 539} 540 |
479static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev) | 541static int kirkwood_i2s_dev_remove(struct platform_device *pdev) |
480{ 481 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); 482 483 snd_soc_unregister_dai(&pdev->dev); 484 | 542{ 543 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); 544 545 snd_soc_unregister_dai(&pdev->dev); 546 |
547 if (!IS_ERR(priv->extclk)) { 548 clk_disable_unprepare(priv->extclk); 549 clk_put(priv->extclk); 550 } |
|
485 clk_disable_unprepare(priv->clk); | 551 clk_disable_unprepare(priv->clk); |
486 clk_put(priv->clk); | |
487 | 552 |
488 iounmap(priv->io); 489 release_mem_region(priv->mem->start, SZ_16K); 490 kfree(priv); 491 | |
492 return 0; 493} 494 495static struct platform_driver kirkwood_i2s_driver = { 496 .probe = kirkwood_i2s_dev_probe, | 553 return 0; 554} 555 556static struct platform_driver kirkwood_i2s_driver = { 557 .probe = kirkwood_i2s_dev_probe, |
497 .remove = __devexit_p(kirkwood_i2s_dev_remove), | 558 .remove = kirkwood_i2s_dev_remove, |
498 .driver = { 499 .name = DRV_NAME, 500 .owner = THIS_MODULE, 501 }, 502}; 503 504module_platform_driver(kirkwood_i2s_driver); 505 506/* Module information */ 507MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>"); 508MODULE_DESCRIPTION("Kirkwood I2S SoC Interface"); 509MODULE_LICENSE("GPL"); 510MODULE_ALIAS("platform:kirkwood-i2s"); | 559 .driver = { 560 .name = DRV_NAME, 561 .owner = THIS_MODULE, 562 }, 563}; 564 565module_platform_driver(kirkwood_i2s_driver); 566 567/* Module information */ 568MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>"); 569MODULE_DESCRIPTION("Kirkwood I2S SoC Interface"); 570MODULE_LICENSE("GPL"); 571MODULE_ALIAS("platform:kirkwood-i2s"); |