aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-08-08 08:30:29 -0400
committerTakashi Iwai <tiwai@suse.de>2011-08-08 08:30:29 -0400
commit0a2d31b62dba9b5b92a38c67c9cc42630513662a (patch)
treef755d74ec85248de645e10c45ed1a2ed467530f6 /sound
parent8039290a91c5dc4414093c086987a5d7738fe2fd (diff)
parentdf944f66784e6d4f2f50739263a4947885d8b6ae (diff)
Merge branch 'fix/kconfig' into for-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c9
-rw-r--r--sound/atmel/abdac.c2
-rw-r--r--sound/atmel/ac97c.c2
-rw-r--r--sound/core/info.c2
-rw-r--r--sound/drivers/pcsp/pcsp.h8
-rw-r--r--sound/i2c/other/tea575x-tuner.c143
-rw-r--r--sound/isa/msnd/msnd.h2
-rw-r--r--sound/pci/Kconfig10
-rw-r--r--sound/pci/echoaudio/darla20.c2
-rw-r--r--sound/pci/echoaudio/darla24.c2
-rw-r--r--sound/pci/echoaudio/echo3g.c2
-rw-r--r--sound/pci/echoaudio/gina20.c2
-rw-r--r--sound/pci/echoaudio/gina24.c2
-rw-r--r--sound/pci/echoaudio/indigo.c2
-rw-r--r--sound/pci/echoaudio/indigodj.c2
-rw-r--r--sound/pci/echoaudio/indigodjx.c2
-rw-r--r--sound/pci/echoaudio/indigoio.c2
-rw-r--r--sound/pci/echoaudio/indigoiox.c2
-rw-r--r--sound/pci/echoaudio/layla20.c2
-rw-r--r--sound/pci/echoaudio/layla24.c2
-rw-r--r--sound/pci/echoaudio/mia.c2
-rw-r--r--sound/pci/echoaudio/mona.c2
-rw-r--r--sound/pci/ice1712/ice1712.c2
-rw-r--r--sound/pci/lx6464es/lx6464es.h2
-rw-r--r--sound/ppc/pmac.c9
-rw-r--r--sound/soc/codecs/Kconfig3
-rw-r--r--sound/soc/codecs/twl4030.c22
-rw-r--r--sound/soc/codecs/twl6040.c733
-rw-r--r--sound/soc/codecs/twl6040.h119
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c4
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c8
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c141
-rw-r--r--sound/soc/ep93xx/snappercl15.c4
-rw-r--r--sound/soc/fsl/mpc5200_dma.c2
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c4
-rw-r--r--sound/soc/omap/ams-delta.c2
-rw-r--r--sound/soc/omap/sdp3430.c2
-rw-r--r--sound/soc/omap/sdp4430.c52
-rw-r--r--sound/soc/omap/zoom2.c2
-rw-r--r--sound/sparc/dbri.c2
40 files changed, 514 insertions, 805 deletions
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
index 3ff8cc5f487a..010658335881 100644
--- a/sound/aoa/soundbus/i2sbus/core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -262,8 +262,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
262 */ 262 */
263 dev->allocated_resource[i] = 263 dev->allocated_resource[i] =
264 request_mem_region(dev->resources[i].start, 264 request_mem_region(dev->resources[i].start,
265 dev->resources[i].end - 265 resource_size(&dev->resources[i]),
266 dev->resources[i].start + 1,
267 dev->rnames[i]); 266 dev->rnames[i]);
268 if (!dev->allocated_resource[i]) { 267 if (!dev->allocated_resource[i]) {
269 printk(KERN_ERR "i2sbus: failed to claim resource %d!\n", i); 268 printk(KERN_ERR "i2sbus: failed to claim resource %d!\n", i);
@@ -272,19 +271,19 @@ static int i2sbus_add_dev(struct macio_dev *macio,
272 } 271 }
273 272
274 r = &dev->resources[aoa_resource_i2smmio]; 273 r = &dev->resources[aoa_resource_i2smmio];
275 rlen = r->end - r->start + 1; 274 rlen = resource_size(r);
276 if (rlen < sizeof(struct i2s_interface_regs)) 275 if (rlen < sizeof(struct i2s_interface_regs))
277 goto err; 276 goto err;
278 dev->intfregs = ioremap(r->start, rlen); 277 dev->intfregs = ioremap(r->start, rlen);
279 278
280 r = &dev->resources[aoa_resource_txdbdma]; 279 r = &dev->resources[aoa_resource_txdbdma];
281 rlen = r->end - r->start + 1; 280 rlen = resource_size(r);
282 if (rlen < sizeof(struct dbdma_regs)) 281 if (rlen < sizeof(struct dbdma_regs))
283 goto err; 282 goto err;
284 dev->out.dbdma = ioremap(r->start, rlen); 283 dev->out.dbdma = ioremap(r->start, rlen);
285 284
286 r = &dev->resources[aoa_resource_rxdbdma]; 285 r = &dev->resources[aoa_resource_rxdbdma];
287 rlen = r->end - r->start + 1; 286 rlen = resource_size(r);
288 if (rlen < sizeof(struct dbdma_regs)) 287 if (rlen < sizeof(struct dbdma_regs))
289 goto err; 288 goto err;
290 dev->in.dbdma = ioremap(r->start, rlen); 289 dev->in.dbdma = ioremap(r->start, rlen);
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index bfee60c4d4c0..6fd9391b3a6c 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -448,7 +448,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
448 goto out_free_card; 448 goto out_free_card;
449 } 449 }
450 450
451 dac->regs = ioremap(regs->start, regs->end - regs->start + 1); 451 dac->regs = ioremap(regs->start, resource_size(regs));
452 if (!dac->regs) { 452 if (!dac->regs) {
453 dev_dbg(&pdev->dev, "could not remap register memory\n"); 453 dev_dbg(&pdev->dev, "could not remap register memory\n");
454 goto out_free_card; 454 goto out_free_card;
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index ac35222ad0dd..6e5addeb236b 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -971,7 +971,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
971 chip->card = card; 971 chip->card = card;
972 chip->pclk = pclk; 972 chip->pclk = pclk;
973 chip->pdev = pdev; 973 chip->pdev = pdev;
974 chip->regs = ioremap(regs->start, regs->end - regs->start + 1); 974 chip->regs = ioremap(regs->start, resource_size(regs));
975 975
976 if (!chip->regs) { 976 if (!chip->regs) {
977 dev_dbg(&pdev->dev, "could not remap register memory\n"); 977 dev_dbg(&pdev->dev, "could not remap register memory\n");
diff --git a/sound/core/info.c b/sound/core/info.c
index 7077f601da5a..601f0ebb677b 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -531,7 +531,7 @@ int __init snd_info_init(void)
531{ 531{
532 struct proc_dir_entry *p; 532 struct proc_dir_entry *p;
533 533
534 p = create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL); 534 p = proc_mkdir("asound", NULL);
535 if (p == NULL) 535 if (p == NULL)
536 return -ENOMEM; 536 return -ENOMEM;
537 snd_proc_root = p; 537 snd_proc_root = p;
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 4ff6c8cc5077..fc7a2dc410a1 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -10,14 +10,8 @@
10#define __PCSP_H__ 10#define __PCSP_H__
11 11
12#include <linux/hrtimer.h> 12#include <linux/hrtimer.h>
13#include <linux/i8253.h>
13#include <linux/timex.h> 14#include <linux/timex.h>
14#if defined(CONFIG_MIPS) || defined(CONFIG_X86)
15/* Use the global PIT lock ! */
16#include <asm/i8253.h>
17#else
18#include <asm/8253pit.h>
19static DEFINE_RAW_SPINLOCK(i8253_lock);
20#endif
21 15
22#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */ 16#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */
23#define PCSP_DEBUG 0 17#define PCSP_DEBUG 0
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 4831800239d3..484a35b3715f 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -22,11 +22,11 @@
22 22
23#include <asm/io.h> 23#include <asm/io.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/interrupt.h>
26#include <linux/init.h> 25#include <linux/init.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
28#include <linux/version.h> 27#include <linux/version.h>
29#include <sound/core.h> 28#include <media/v4l2-dev.h>
29#include <media/v4l2-ioctl.h>
30#include <sound/tea575x-tuner.h> 30#include <sound/tea575x-tuner.h>
31 31
32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -62,17 +62,6 @@ module_param(radio_nr, int, 0);
62#define TEA575X_BIT_DUMMY (1<<15) /* buffer */ 62#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
63#define TEA575X_BIT_FREQ_MASK 0x7fff 63#define TEA575X_BIT_FREQ_MASK 0x7fff
64 64
65static struct v4l2_queryctrl radio_qctrl[] = {
66 {
67 .id = V4L2_CID_AUDIO_MUTE,
68 .name = "Mute",
69 .minimum = 0,
70 .maximum = 1,
71 .default_value = 1,
72 .type = V4L2_CTRL_TYPE_BOOLEAN,
73 }
74};
75
76/* 65/*
77 * lowlevel part 66 * lowlevel part
78 */ 67 */
@@ -266,83 +255,23 @@ static int vidioc_s_audio(struct file *file, void *priv,
266 return 0; 255 return 0;
267} 256}
268 257
269static int vidioc_queryctrl(struct file *file, void *priv, 258static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
270 struct v4l2_queryctrl *qc)
271{
272 int i;
273
274 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
275 if (qc->id && qc->id == radio_qctrl[i].id) {
276 memcpy(qc, &(radio_qctrl[i]),
277 sizeof(*qc));
278 return 0;
279 }
280 }
281 return -EINVAL;
282}
283
284static int vidioc_g_ctrl(struct file *file, void *priv,
285 struct v4l2_control *ctrl)
286{ 259{
287 struct snd_tea575x *tea = video_drvdata(file); 260 struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler);
288 261
289 switch (ctrl->id) { 262 switch (ctrl->id) {
290 case V4L2_CID_AUDIO_MUTE: 263 case V4L2_CID_AUDIO_MUTE:
291 ctrl->value = tea->mute; 264 tea->mute = ctrl->val;
265 snd_tea575x_set_freq(tea);
292 return 0; 266 return 0;
293 } 267 }
294 return -EINVAL;
295}
296 268
297static int vidioc_s_ctrl(struct file *file, void *priv,
298 struct v4l2_control *ctrl)
299{
300 struct snd_tea575x *tea = video_drvdata(file);
301
302 switch (ctrl->id) {
303 case V4L2_CID_AUDIO_MUTE:
304 if (tea->mute != ctrl->value) {
305 tea->mute = ctrl->value;
306 snd_tea575x_set_freq(tea);
307 }
308 return 0;
309 }
310 return -EINVAL; 269 return -EINVAL;
311} 270}
312 271
313static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
314{
315 *i = 0;
316 return 0;
317}
318
319static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
320{
321 if (i != 0)
322 return -EINVAL;
323 return 0;
324}
325
326static int snd_tea575x_exclusive_open(struct file *file)
327{
328 struct snd_tea575x *tea = video_drvdata(file);
329
330 return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0;
331}
332
333static int snd_tea575x_exclusive_release(struct file *file)
334{
335 struct snd_tea575x *tea = video_drvdata(file);
336
337 clear_bit(0, &tea->in_use);
338 return 0;
339}
340
341static const struct v4l2_file_operations tea575x_fops = { 272static const struct v4l2_file_operations tea575x_fops = {
342 .owner = THIS_MODULE, 273 .owner = THIS_MODULE,
343 .open = snd_tea575x_exclusive_open, 274 .unlocked_ioctl = video_ioctl2,
344 .release = snd_tea575x_exclusive_release,
345 .ioctl = video_ioctl2,
346}; 275};
347 276
348static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { 277static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
@@ -351,20 +280,19 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
351 .vidioc_s_tuner = vidioc_s_tuner, 280 .vidioc_s_tuner = vidioc_s_tuner,
352 .vidioc_g_audio = vidioc_g_audio, 281 .vidioc_g_audio = vidioc_g_audio,
353 .vidioc_s_audio = vidioc_s_audio, 282 .vidioc_s_audio = vidioc_s_audio,
354 .vidioc_g_input = vidioc_g_input,
355 .vidioc_s_input = vidioc_s_input,
356 .vidioc_g_frequency = vidioc_g_frequency, 283 .vidioc_g_frequency = vidioc_g_frequency,
357 .vidioc_s_frequency = vidioc_s_frequency, 284 .vidioc_s_frequency = vidioc_s_frequency,
358 .vidioc_queryctrl = vidioc_queryctrl,
359 .vidioc_g_ctrl = vidioc_g_ctrl,
360 .vidioc_s_ctrl = vidioc_s_ctrl,
361}; 285};
362 286
363static struct video_device tea575x_radio = { 287static struct video_device tea575x_radio = {
364 .name = "tea575x-tuner", 288 .name = "tea575x-tuner",
365 .fops = &tea575x_fops, 289 .fops = &tea575x_fops,
366 .ioctl_ops = &tea575x_ioctl_ops, 290 .ioctl_ops = &tea575x_ioctl_ops,
367 .release = video_device_release, 291 .release = video_device_release_empty,
292};
293
294static const struct v4l2_ctrl_ops tea575x_ctrl_ops = {
295 .s_ctrl = tea575x_s_ctrl,
368}; 296};
369 297
370/* 298/*
@@ -373,7 +301,6 @@ static struct video_device tea575x_radio = {
373int snd_tea575x_init(struct snd_tea575x *tea) 301int snd_tea575x_init(struct snd_tea575x *tea)
374{ 302{
375 int retval; 303 int retval;
376 struct video_device *tea575x_radio_inst;
377 304
378 tea->mute = 1; 305 tea->mute = 1;
379 306
@@ -381,43 +308,49 @@ int snd_tea575x_init(struct snd_tea575x *tea)
381 if (snd_tea575x_read(tea) != 0x55AA) 308 if (snd_tea575x_read(tea) != 0x55AA)
382 return -ENODEV; 309 return -ENODEV;
383 310
384 tea->in_use = 0;
385 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; 311 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
386 tea->freq = 90500 * 16; /* 90.5Mhz default */ 312 tea->freq = 90500 * 16; /* 90.5Mhz default */
313 snd_tea575x_set_freq(tea);
387 314
388 tea575x_radio_inst = video_device_alloc(); 315 tea->vd = tea575x_radio;
389 if (tea575x_radio_inst == NULL) { 316 video_set_drvdata(&tea->vd, tea);
390 printk(KERN_ERR "tea575x-tuner: not enough memory\n"); 317 mutex_init(&tea->mutex);
391 return -ENOMEM; 318 tea->vd.lock = &tea->mutex;
392 }
393 319
394 memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); 320 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
321 tea->vd.ctrl_handler = &tea->ctrl_handler;
322 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
323 retval = tea->ctrl_handler.error;
324 if (retval) {
325 printk(KERN_ERR "tea575x-tuner: can't initialize controls\n");
326 v4l2_ctrl_handler_free(&tea->ctrl_handler);
327 return retval;
328 }
395 329
396 strcpy(tea575x_radio.name, tea->tea5759 ? 330 if (tea->ext_init) {
397 "TEA5759 radio" : "TEA5757 radio"); 331 retval = tea->ext_init(tea);
332 if (retval) {
333 v4l2_ctrl_handler_free(&tea->ctrl_handler);
334 return retval;
335 }
336 }
398 337
399 video_set_drvdata(tea575x_radio_inst, tea); 338 v4l2_ctrl_handler_setup(&tea->ctrl_handler);
400 339
401 retval = video_register_device(tea575x_radio_inst, 340 retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, radio_nr);
402 VFL_TYPE_RADIO, radio_nr);
403 if (retval) { 341 if (retval) {
404 printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 342 printk(KERN_ERR "tea575x-tuner: can't register video device!\n");
405 kfree(tea575x_radio_inst); 343 v4l2_ctrl_handler_free(&tea->ctrl_handler);
406 return retval; 344 return retval;
407 } 345 }
408 346
409 snd_tea575x_set_freq(tea);
410 tea->vd = tea575x_radio_inst;
411
412 return 0; 347 return 0;
413} 348}
414 349
415void snd_tea575x_exit(struct snd_tea575x *tea) 350void snd_tea575x_exit(struct snd_tea575x *tea)
416{ 351{
417 if (tea->vd) { 352 video_unregister_device(&tea->vd);
418 video_unregister_device(tea->vd); 353 v4l2_ctrl_handler_free(&tea->ctrl_handler);
419 tea->vd = NULL;
420 }
421} 354}
422 355
423static int __init alsa_tea575x_module_init(void) 356static int __init alsa_tea575x_module_init(void)
diff --git a/sound/isa/msnd/msnd.h b/sound/isa/msnd/msnd.h
index 3773e242b58e..a168ba3313ac 100644
--- a/sound/isa/msnd/msnd.h
+++ b/sound/isa/msnd/msnd.h
@@ -249,7 +249,7 @@ struct snd_msnd {
249 249
250 /* State variables */ 250 /* State variables */
251 enum { msndClassic, msndPinnacle } type; 251 enum { msndClassic, msndPinnacle } type;
252 mode_t mode; 252 fmode_t mode;
253 unsigned long flags; 253 unsigned long flags;
254#define F_RESETTING 0 254#define F_RESETTING 0
255#define F_HAVEDIGITAL 1 255#define F_HAVEDIGITAL 1
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index e90d103e177e..88168044375f 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,5 +1,10 @@
1# ALSA PCI drivers 1# ALSA PCI drivers
2 2
3config SND_TEA575X
4 tristate
5 depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2
6 default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2
7
3menuconfig SND_PCI 8menuconfig SND_PCI
4 bool "PCI sound devices" 9 bool "PCI sound devices"
5 depends on PCI 10 depends on PCI
@@ -563,11 +568,6 @@ config SND_FM801_TEA575X_BOOL
563 FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and 568 FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
564 SF64-PCR) into the snd-fm801 driver. 569 SF64-PCR) into the snd-fm801 driver.
565 570
566config SND_TEA575X
567 tristate
568 depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO
569 default SND_FM801 || SND_ES1968
570
571source "sound/pci/hda/Kconfig" 571source "sound/pci/hda/Kconfig"
572 572
573config SND_HDSP 573config SND_HDSP
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
index fe7ad64dccd7..43c7e12bc05d 100644
--- a/sound/pci/echoaudio/darla20.c
+++ b/sound/pci/echoaudio/darla20.c
@@ -52,7 +52,7 @@
52#include <sound/asoundef.h> 52#include <sound/asoundef.h>
53#include <sound/initval.h> 53#include <sound/initval.h>
54#include <asm/io.h> 54#include <asm/io.h>
55#include <asm/atomic.h> 55#include <linux/atomic.h>
56#include "echoaudio.h" 56#include "echoaudio.h"
57 57
58MODULE_FIRMWARE("ea/darla20_dsp.fw"); 58MODULE_FIRMWARE("ea/darla20_dsp.fw");
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
index d1fd34b1a8e3..95b03306e026 100644
--- a/sound/pci/echoaudio/darla24.c
+++ b/sound/pci/echoaudio/darla24.c
@@ -56,7 +56,7 @@
56#include <sound/asoundef.h> 56#include <sound/asoundef.h>
57#include <sound/initval.h> 57#include <sound/initval.h>
58#include <asm/io.h> 58#include <asm/io.h>
59#include <asm/atomic.h> 59#include <linux/atomic.h>
60#include "echoaudio.h" 60#include "echoaudio.h"
61 61
62MODULE_FIRMWARE("ea/darla24_dsp.fw"); 62MODULE_FIRMWARE("ea/darla24_dsp.fw");
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
index 1dffdc54416d..8723c40183e6 100644
--- a/sound/pci/echoaudio/echo3g.c
+++ b/sound/pci/echoaudio/echo3g.c
@@ -64,7 +64,7 @@
64#include <sound/initval.h> 64#include <sound/initval.h>
65#include <sound/rawmidi.h> 65#include <sound/rawmidi.h>
66#include <asm/io.h> 66#include <asm/io.h>
67#include <asm/atomic.h> 67#include <linux/atomic.h>
68#include "echoaudio.h" 68#include "echoaudio.h"
69 69
70MODULE_FIRMWARE("ea/loader_dsp.fw"); 70MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
index 050e54aa693f..0058c67115df 100644
--- a/sound/pci/echoaudio/gina20.c
+++ b/sound/pci/echoaudio/gina20.c
@@ -56,7 +56,7 @@
56#include <sound/asoundef.h> 56#include <sound/asoundef.h>
57#include <sound/initval.h> 57#include <sound/initval.h>
58#include <asm/io.h> 58#include <asm/io.h>
59#include <asm/atomic.h> 59#include <linux/atomic.h>
60#include "echoaudio.h" 60#include "echoaudio.h"
61 61
62MODULE_FIRMWARE("ea/gina20_dsp.fw"); 62MODULE_FIRMWARE("ea/gina20_dsp.fw");
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
index 5748fc6d29d6..14e4925e76cc 100644
--- a/sound/pci/echoaudio/gina24.c
+++ b/sound/pci/echoaudio/gina24.c
@@ -62,7 +62,7 @@
62#include <sound/asoundef.h> 62#include <sound/asoundef.h>
63#include <sound/initval.h> 63#include <sound/initval.h>
64#include <asm/io.h> 64#include <asm/io.h>
65#include <asm/atomic.h> 65#include <linux/atomic.h>
66#include "echoaudio.h" 66#include "echoaudio.h"
67 67
68MODULE_FIRMWARE("ea/loader_dsp.fw"); 68MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
index 4ae5e35cb5f1..f416b154f146 100644
--- a/sound/pci/echoaudio/indigo.c
+++ b/sound/pci/echoaudio/indigo.c
@@ -54,7 +54,7 @@
54#include <sound/asoundef.h> 54#include <sound/asoundef.h>
55#include <sound/initval.h> 55#include <sound/initval.h>
56#include <asm/io.h> 56#include <asm/io.h>
57#include <asm/atomic.h> 57#include <linux/atomic.h>
58#include "echoaudio.h" 58#include "echoaudio.h"
59 59
60MODULE_FIRMWARE("ea/loader_dsp.fw"); 60MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
index 3550715bab1c..e594a3b2766e 100644
--- a/sound/pci/echoaudio/indigodj.c
+++ b/sound/pci/echoaudio/indigodj.c
@@ -54,7 +54,7 @@
54#include <sound/asoundef.h> 54#include <sound/asoundef.h>
55#include <sound/initval.h> 55#include <sound/initval.h>
56#include <asm/io.h> 56#include <asm/io.h>
57#include <asm/atomic.h> 57#include <linux/atomic.h>
58#include "echoaudio.h" 58#include "echoaudio.h"
59 59
60MODULE_FIRMWARE("ea/loader_dsp.fw"); 60MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c
index 19b191fd0120..f0d00bfceee5 100644
--- a/sound/pci/echoaudio/indigodjx.c
+++ b/sound/pci/echoaudio/indigodjx.c
@@ -54,7 +54,7 @@
54#include <sound/pcm_params.h> 54#include <sound/pcm_params.h>
55#include <sound/asoundef.h> 55#include <sound/asoundef.h>
56#include <sound/initval.h> 56#include <sound/initval.h>
57#include <asm/atomic.h> 57#include <linux/atomic.h>
58#include "echoaudio.h" 58#include "echoaudio.h"
59 59
60MODULE_FIRMWARE("ea/loader_dsp.fw"); 60MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
index a9fcedf317a4..1af0037304c6 100644
--- a/sound/pci/echoaudio/indigoio.c
+++ b/sound/pci/echoaudio/indigoio.c
@@ -55,7 +55,7 @@
55#include <sound/asoundef.h> 55#include <sound/asoundef.h>
56#include <sound/initval.h> 56#include <sound/initval.h>
57#include <asm/io.h> 57#include <asm/io.h>
58#include <asm/atomic.h> 58#include <linux/atomic.h>
59#include "echoaudio.h" 59#include "echoaudio.h"
60 60
61MODULE_FIRMWARE("ea/loader_dsp.fw"); 61MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c
index bcdfac63212c..0b51163452b5 100644
--- a/sound/pci/echoaudio/indigoiox.c
+++ b/sound/pci/echoaudio/indigoiox.c
@@ -55,7 +55,7 @@
55#include <sound/pcm_params.h> 55#include <sound/pcm_params.h>
56#include <sound/asoundef.h> 56#include <sound/asoundef.h>
57#include <sound/initval.h> 57#include <sound/initval.h>
58#include <asm/atomic.h> 58#include <linux/atomic.h>
59#include "echoaudio.h" 59#include "echoaudio.h"
60 60
61MODULE_FIRMWARE("ea/loader_dsp.fw"); 61MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
index d3a98c5dac86..3f63ab8dfff3 100644
--- a/sound/pci/echoaudio/layla20.c
+++ b/sound/pci/echoaudio/layla20.c
@@ -62,7 +62,7 @@
62#include <sound/initval.h> 62#include <sound/initval.h>
63#include <sound/rawmidi.h> 63#include <sound/rawmidi.h>
64#include <asm/io.h> 64#include <asm/io.h>
65#include <asm/atomic.h> 65#include <linux/atomic.h>
66#include "echoaudio.h" 66#include "echoaudio.h"
67 67
68MODULE_FIRMWARE("ea/layla20_dsp.fw"); 68MODULE_FIRMWARE("ea/layla20_dsp.fw");
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
index 2a1dca6dce17..283137244472 100644
--- a/sound/pci/echoaudio/layla24.c
+++ b/sound/pci/echoaudio/layla24.c
@@ -64,7 +64,7 @@
64#include <sound/initval.h> 64#include <sound/initval.h>
65#include <sound/rawmidi.h> 65#include <sound/rawmidi.h>
66#include <asm/io.h> 66#include <asm/io.h>
67#include <asm/atomic.h> 67#include <linux/atomic.h>
68#include "echoaudio.h" 68#include "echoaudio.h"
69 69
70MODULE_FIRMWARE("ea/loader_dsp.fw"); 70MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index 9cdf14cfdd74..eddaeb4da50e 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -63,7 +63,7 @@
63#include <sound/initval.h> 63#include <sound/initval.h>
64#include <sound/rawmidi.h> 64#include <sound/rawmidi.h>
65#include <asm/io.h> 65#include <asm/io.h>
66#include <asm/atomic.h> 66#include <linux/atomic.h>
67#include "echoaudio.h" 67#include "echoaudio.h"
68 68
69MODULE_FIRMWARE("ea/loader_dsp.fw"); 69MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
index 1047be405ebe..0364011c237d 100644
--- a/sound/pci/echoaudio/mona.c
+++ b/sound/pci/echoaudio/mona.c
@@ -60,7 +60,7 @@
60#include <sound/asoundef.h> 60#include <sound/asoundef.h>
61#include <sound/initval.h> 61#include <sound/initval.h>
62#include <asm/io.h> 62#include <asm/io.h>
63#include <asm/atomic.h> 63#include <linux/atomic.h>
64#include "echoaudio.h" 64#include "echoaudio.h"
65 65
66MODULE_FIRMWARE("ea/loader_dsp.fw"); 66MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index be06fb3e45a1..0ccc0eb75775 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -87,7 +87,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
87static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ 87static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
88static char *model[SNDRV_CARDS]; 88static char *model[SNDRV_CARDS];
89static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */ 89static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */
90static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transciever reset timeout value in msec */ 90static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transceiver reset timeout value in msec */
91static int dxr_enable[SNDRV_CARDS]; /* DXR enable for DMX6FIRE */ 91static int dxr_enable[SNDRV_CARDS]; /* DXR enable for DMX6FIRE */
92 92
93module_param_array(index, int, NULL, 0444); 93module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h
index e2a124ae27e8..6792eda9c9a5 100644
--- a/sound/pci/lx6464es/lx6464es.h
+++ b/sound/pci/lx6464es/lx6464es.h
@@ -26,7 +26,7 @@
26#define LX6464ES_H 26#define LX6464ES_H
27 27
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include <asm/atomic.h> 29#include <linux/atomic.h>
30 30
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/pcm.h> 32#include <sound/pcm.h>
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 3ecbd67f88c9..ab96cde7417b 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -881,8 +881,7 @@ static int snd_pmac_free(struct snd_pmac *chip)
881 for (i = 0; i < 3; i++) { 881 for (i = 0; i < 3; i++) {
882 if (chip->requested & (1 << i)) 882 if (chip->requested & (1 << i))
883 release_mem_region(chip->rsrc[i].start, 883 release_mem_region(chip->rsrc[i].start,
884 chip->rsrc[i].end - 884 resource_size(&chip->rsrc[i]));
885 chip->rsrc[i].start + 1);
886 } 885 }
887 } 886 }
888 887
@@ -1228,8 +1227,7 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
1228 goto __error; 1227 goto __error;
1229 } 1228 }
1230 if (request_mem_region(chip->rsrc[i].start, 1229 if (request_mem_region(chip->rsrc[i].start,
1231 chip->rsrc[i].end - 1230 resource_size(&chip->rsrc[i]),
1232 chip->rsrc[i].start + 1,
1233 rnames[i]) == NULL) { 1231 rnames[i]) == NULL) {
1234 printk(KERN_ERR "snd: can't request rsrc " 1232 printk(KERN_ERR "snd: can't request rsrc "
1235 " %d (%s: %pR)\n", 1233 " %d (%s: %pR)\n",
@@ -1254,8 +1252,7 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
1254 goto __error; 1252 goto __error;
1255 } 1253 }
1256 if (request_mem_region(chip->rsrc[i].start, 1254 if (request_mem_region(chip->rsrc[i].start,
1257 chip->rsrc[i].end - 1255 resource_size(&chip->rsrc[i]),
1258 chip->rsrc[i].start + 1,
1259 rnames[i]) == NULL) { 1256 rnames[i]) == NULL) {
1260 printk(KERN_ERR "snd: can't request rsrc " 1257 printk(KERN_ERR "snd: can't request rsrc "
1261 " %d (%s: %pR)\n", 1258 " %d (%s: %pR)\n",
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 36a030f1d1f5..379b2e3afd98 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -250,10 +250,11 @@ config SND_SOC_TLV320DAC33
250 tristate 250 tristate
251 251
252config SND_SOC_TWL4030 252config SND_SOC_TWL4030
253 select TWL4030_CODEC 253 select MFD_TWL4030_AUDIO
254 tristate 254 tristate
255 255
256config SND_SOC_TWL6040 256config SND_SOC_TWL6040
257 select TWL6040_CORE
257 tristate 258 tristate
258 259
259config SND_SOC_UDA134X 260config SND_SOC_UDA134X
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index bec788b12613..71674bec9604 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -36,7 +36,7 @@
36#include <sound/tlv.h> 36#include <sound/tlv.h>
37 37
38/* Register descriptions are here */ 38/* Register descriptions are here */
39#include <linux/mfd/twl4030-codec.h> 39#include <linux/mfd/twl4030-audio.h>
40 40
41/* Shadow register used by the audio driver */ 41/* Shadow register used by the audio driver */
42#define TWL4030_REG_SW_SHADOW 0x4A 42#define TWL4030_REG_SW_SHADOW 0x4A
@@ -251,9 +251,9 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
251 return; 251 return;
252 252
253 if (enable) 253 if (enable)
254 mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER); 254 mode = twl4030_audio_enable_resource(TWL4030_AUDIO_RES_POWER);
255 else 255 else
256 mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); 256 mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
257 257
258 if (mode >= 0) { 258 if (mode >= 0) {
259 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode); 259 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
@@ -297,7 +297,7 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
297 297
298static void twl4030_init_chip(struct snd_soc_codec *codec) 298static void twl4030_init_chip(struct snd_soc_codec *codec)
299{ 299{
300 struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev); 300 struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
301 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 301 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
302 u8 reg, byte; 302 u8 reg, byte;
303 int i = 0; 303 int i = 0;
@@ -375,13 +375,13 @@ static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
375 if (enable) { 375 if (enable) {
376 twl4030->apll_enabled++; 376 twl4030->apll_enabled++;
377 if (twl4030->apll_enabled == 1) 377 if (twl4030->apll_enabled == 1)
378 status = twl4030_codec_enable_resource( 378 status = twl4030_audio_enable_resource(
379 TWL4030_CODEC_RES_APLL); 379 TWL4030_AUDIO_RES_APLL);
380 } else { 380 } else {
381 twl4030->apll_enabled--; 381 twl4030->apll_enabled--;
382 if (!twl4030->apll_enabled) 382 if (!twl4030->apll_enabled)
383 status = twl4030_codec_disable_resource( 383 status = twl4030_audio_disable_resource(
384 TWL4030_CODEC_RES_APLL); 384 TWL4030_AUDIO_RES_APLL);
385 } 385 }
386 386
387 if (status >= 0) 387 if (status >= 0)
@@ -732,7 +732,7 @@ static int aif_event(struct snd_soc_dapm_widget *w,
732 732
733static void headset_ramp(struct snd_soc_codec *codec, int ramp) 733static void headset_ramp(struct snd_soc_codec *codec, int ramp)
734{ 734{
735 struct twl4030_codec_audio_data *pdata = codec->dev->platform_data; 735 struct twl4030_codec_data *pdata = codec->dev->platform_data;
736 unsigned char hs_gain, hs_pop; 736 unsigned char hs_gain, hs_pop;
737 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 737 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
738 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 738 /* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -2260,7 +2260,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2260 } 2260 }
2261 snd_soc_codec_set_drvdata(codec, twl4030); 2261 snd_soc_codec_set_drvdata(codec, twl4030);
2262 /* Set the defaults, and power up the codec */ 2262 /* Set the defaults, and power up the codec */
2263 twl4030->sysclk = twl4030_codec_get_mclk() / 1000; 2263 twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
2264 codec->dapm.idle_bias_off = 1; 2264 codec->dapm.idle_bias_off = 1;
2265 2265
2266 twl4030_init_chip(codec); 2266 twl4030_init_chip(codec);
@@ -2297,7 +2297,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2297 2297
2298static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2298static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2299{ 2299{
2300 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data; 2300 struct twl4030_codec_data *pdata = pdev->dev.platform_data;
2301 2301
2302 if (!pdata) { 2302 if (!pdata) {
2303 dev_err(&pdev->dev, "platform_data is missing\n"); 2303 dev_err(&pdev->dev, "platform_data is missing\n");
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index cd63bba623df..443032b3b329 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -24,11 +24,10 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/pm.h> 26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/gpio.h>
29#include <linux/platform_device.h> 27#include <linux/platform_device.h>
30#include <linux/slab.h> 28#include <linux/slab.h>
31#include <linux/i2c/twl.h> 29#include <linux/i2c/twl.h>
30#include <linux/mfd/twl6040.h>
32 31
33#include <sound/core.h> 32#include <sound/core.h>
34#include <sound/pcm.h> 33#include <sound/pcm.h>
@@ -77,14 +76,19 @@ struct twl6040_jack_data {
77 76
78/* codec private data */ 77/* codec private data */
79struct twl6040_data { 78struct twl6040_data {
80 int audpwron; 79 int plug_irq;
81 int naudint;
82 int codec_powered; 80 int codec_powered;
83 int pll; 81 int pll;
84 int non_lp; 82 int non_lp;
83 int pll_power_mode;
84 int hs_power_mode;
85 int hs_power_mode_locked;
86 unsigned int clk_in;
85 unsigned int sysclk; 87 unsigned int sysclk;
86 struct snd_pcm_hw_constraint_list *sysclk_constraints; 88 u16 hs_left_step;
87 struct completion ready; 89 u16 hs_right_step;
90 u16 hf_left_step;
91 u16 hf_right_step;
88 struct twl6040_jack_data hs_jack; 92 struct twl6040_jack_data hs_jack;
89 struct snd_soc_codec *codec; 93 struct snd_soc_codec *codec;
90 struct workqueue_struct *workqueue; 94 struct workqueue_struct *workqueue;
@@ -206,6 +210,32 @@ static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
206 TWL6040_REG_DLB, 210 TWL6040_REG_DLB,
207}; 211};
208 212
213/* set of rates for each pll: low-power and high-performance */
214static unsigned int lp_rates[] = {
215 8000,
216 11250,
217 16000,
218 22500,
219 32000,
220 44100,
221 48000,
222 88200,
223 96000,
224};
225
226static unsigned int hp_rates[] = {
227 8000,
228 16000,
229 32000,
230 48000,
231 96000,
232};
233
234static struct snd_pcm_hw_constraint_list sysclk_constraints[] = {
235 { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, },
236 { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, },
237};
238
209/* 239/*
210 * read twl6040 register cache 240 * read twl6040 register cache
211 */ 241 */
@@ -239,12 +269,13 @@ static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec,
239static int twl6040_read_reg_volatile(struct snd_soc_codec *codec, 269static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
240 unsigned int reg) 270 unsigned int reg)
241{ 271{
272 struct twl6040 *twl6040 = codec->control_data;
242 u8 value; 273 u8 value;
243 274
244 if (reg >= TWL6040_CACHEREGNUM) 275 if (reg >= TWL6040_CACHEREGNUM)
245 return -EIO; 276 return -EIO;
246 277
247 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &value, reg); 278 value = twl6040_reg_read(twl6040, reg);
248 twl6040_write_reg_cache(codec, reg, value); 279 twl6040_write_reg_cache(codec, reg, value);
249 280
250 return value; 281 return value;
@@ -256,11 +287,13 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
256static int twl6040_write(struct snd_soc_codec *codec, 287static int twl6040_write(struct snd_soc_codec *codec,
257 unsigned int reg, unsigned int value) 288 unsigned int reg, unsigned int value)
258{ 289{
290 struct twl6040 *twl6040 = codec->control_data;
291
259 if (reg >= TWL6040_CACHEREGNUM) 292 if (reg >= TWL6040_CACHEREGNUM)
260 return -EIO; 293 return -EIO;
261 294
262 twl6040_write_reg_cache(codec, reg, value); 295 twl6040_write_reg_cache(codec, reg, value);
263 return twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, value, reg); 296 return twl6040_reg_write(twl6040, reg, value);
264} 297}
265 298
266static void twl6040_init_vio_regs(struct snd_soc_codec *codec) 299static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
@@ -268,15 +301,21 @@ static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
268 u8 *cache = codec->reg_cache; 301 u8 *cache = codec->reg_cache;
269 int reg, i; 302 int reg, i;
270 303
271 /* allow registers to be accessed by i2c */
272 twl6040_write(codec, TWL6040_REG_ACCCTL, cache[TWL6040_REG_ACCCTL]);
273
274 for (i = 0; i < TWL6040_VIOREGNUM; i++) { 304 for (i = 0; i < TWL6040_VIOREGNUM; i++) {
275 reg = twl6040_vio_reg[i]; 305 reg = twl6040_vio_reg[i];
276 /* skip read-only registers (ASICID, ASICREV, STATUS) */ 306 /*
307 * skip read-only registers (ASICID, ASICREV, STATUS)
308 * and registers shared among MFD children
309 */
277 switch (reg) { 310 switch (reg) {
278 case TWL6040_REG_ASICID: 311 case TWL6040_REG_ASICID:
279 case TWL6040_REG_ASICREV: 312 case TWL6040_REG_ASICREV:
313 case TWL6040_REG_INTID:
314 case TWL6040_REG_INTMR:
315 case TWL6040_REG_NCPCTL:
316 case TWL6040_REG_LDOCTL:
317 case TWL6040_REG_GPOCTL:
318 case TWL6040_REG_ACCCTL:
280 case TWL6040_REG_STATUS: 319 case TWL6040_REG_STATUS:
281 continue; 320 continue;
282 default: 321 default:
@@ -293,6 +332,20 @@ static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
293 332
294 for (i = 0; i < TWL6040_VDDREGNUM; i++) { 333 for (i = 0; i < TWL6040_VDDREGNUM; i++) {
295 reg = twl6040_vdd_reg[i]; 334 reg = twl6040_vdd_reg[i];
335 /* skip vibra and PLL registers */
336 switch (reg) {
337 case TWL6040_REG_VIBCTLL:
338 case TWL6040_REG_VIBDATL:
339 case TWL6040_REG_VIBCTLR:
340 case TWL6040_REG_VIBDATR:
341 case TWL6040_REG_HPPLLCTL:
342 case TWL6040_REG_LPPLLCTL:
343 case TWL6040_REG_LPPLLDIV:
344 continue;
345 default:
346 break;
347 }
348
296 twl6040_write(codec, reg, cache[reg]); 349 twl6040_write(codec, reg, cache[reg]);
297 } 350 }
298} 351}
@@ -317,7 +370,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
317 if (headset->ramp == TWL6040_RAMP_UP) { 370 if (headset->ramp == TWL6040_RAMP_UP) {
318 /* ramp step up */ 371 /* ramp step up */
319 if (val < headset->left_vol) { 372 if (val < headset->left_vol) {
320 val += left_step; 373 if (val + left_step > headset->left_vol)
374 val = headset->left_vol;
375 else
376 val += left_step;
377
321 reg &= ~TWL6040_HSL_VOL_MASK; 378 reg &= ~TWL6040_HSL_VOL_MASK;
322 twl6040_write(codec, TWL6040_REG_HSGAIN, 379 twl6040_write(codec, TWL6040_REG_HSGAIN,
323 (reg | (~val & TWL6040_HSL_VOL_MASK))); 380 (reg | (~val & TWL6040_HSL_VOL_MASK)));
@@ -327,7 +384,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
327 } else if (headset->ramp == TWL6040_RAMP_DOWN) { 384 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
328 /* ramp step down */ 385 /* ramp step down */
329 if (val > 0x0) { 386 if (val > 0x0) {
330 val -= left_step; 387 if ((int)val - (int)left_step < 0)
388 val = 0;
389 else
390 val -= left_step;
391
331 reg &= ~TWL6040_HSL_VOL_MASK; 392 reg &= ~TWL6040_HSL_VOL_MASK;
332 twl6040_write(codec, TWL6040_REG_HSGAIN, reg | 393 twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
333 (~val & TWL6040_HSL_VOL_MASK)); 394 (~val & TWL6040_HSL_VOL_MASK));
@@ -344,7 +405,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
344 if (headset->ramp == TWL6040_RAMP_UP) { 405 if (headset->ramp == TWL6040_RAMP_UP) {
345 /* ramp step up */ 406 /* ramp step up */
346 if (val < headset->right_vol) { 407 if (val < headset->right_vol) {
347 val += right_step; 408 if (val + right_step > headset->right_vol)
409 val = headset->right_vol;
410 else
411 val += right_step;
412
348 reg &= ~TWL6040_HSR_VOL_MASK; 413 reg &= ~TWL6040_HSR_VOL_MASK;
349 twl6040_write(codec, TWL6040_REG_HSGAIN, 414 twl6040_write(codec, TWL6040_REG_HSGAIN,
350 (reg | (~val << TWL6040_HSR_VOL_SHIFT))); 415 (reg | (~val << TWL6040_HSR_VOL_SHIFT)));
@@ -354,7 +419,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
354 } else if (headset->ramp == TWL6040_RAMP_DOWN) { 419 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
355 /* ramp step down */ 420 /* ramp step down */
356 if (val > 0x0) { 421 if (val > 0x0) {
357 val -= right_step; 422 if ((int)val - (int)right_step < 0)
423 val = 0;
424 else
425 val -= right_step;
426
358 reg &= ~TWL6040_HSR_VOL_MASK; 427 reg &= ~TWL6040_HSR_VOL_MASK;
359 twl6040_write(codec, TWL6040_REG_HSGAIN, 428 twl6040_write(codec, TWL6040_REG_HSGAIN,
360 reg | (~val << TWL6040_HSR_VOL_SHIFT)); 429 reg | (~val << TWL6040_HSR_VOL_SHIFT));
@@ -385,7 +454,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
385 if (handsfree->ramp == TWL6040_RAMP_UP) { 454 if (handsfree->ramp == TWL6040_RAMP_UP) {
386 /* ramp step up */ 455 /* ramp step up */
387 if (val < handsfree->left_vol) { 456 if (val < handsfree->left_vol) {
388 val += left_step; 457 if (val + left_step > handsfree->left_vol)
458 val = handsfree->left_vol;
459 else
460 val += left_step;
461
389 reg &= ~TWL6040_HF_VOL_MASK; 462 reg &= ~TWL6040_HF_VOL_MASK;
390 twl6040_write(codec, TWL6040_REG_HFLGAIN, 463 twl6040_write(codec, TWL6040_REG_HFLGAIN,
391 reg | (0x1D - val)); 464 reg | (0x1D - val));
@@ -395,7 +468,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
395 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) { 468 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
396 /* ramp step down */ 469 /* ramp step down */
397 if (val > 0) { 470 if (val > 0) {
398 val -= left_step; 471 if ((int)val - (int)left_step < 0)
472 val = 0;
473 else
474 val -= left_step;
475
399 reg &= ~TWL6040_HF_VOL_MASK; 476 reg &= ~TWL6040_HF_VOL_MASK;
400 twl6040_write(codec, TWL6040_REG_HFLGAIN, 477 twl6040_write(codec, TWL6040_REG_HFLGAIN,
401 reg | (0x1D - val)); 478 reg | (0x1D - val));
@@ -412,7 +489,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
412 if (handsfree->ramp == TWL6040_RAMP_UP) { 489 if (handsfree->ramp == TWL6040_RAMP_UP) {
413 /* ramp step up */ 490 /* ramp step up */
414 if (val < handsfree->right_vol) { 491 if (val < handsfree->right_vol) {
415 val += right_step; 492 if (val + right_step > handsfree->right_vol)
493 val = handsfree->right_vol;
494 else
495 val += right_step;
496
416 reg &= ~TWL6040_HF_VOL_MASK; 497 reg &= ~TWL6040_HF_VOL_MASK;
417 twl6040_write(codec, TWL6040_REG_HFRGAIN, 498 twl6040_write(codec, TWL6040_REG_HFRGAIN,
418 reg | (0x1D - val)); 499 reg | (0x1D - val));
@@ -422,7 +503,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
422 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) { 503 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
423 /* ramp step down */ 504 /* ramp step down */
424 if (val > 0) { 505 if (val > 0) {
425 val -= right_step; 506 if ((int)val - (int)right_step < 0)
507 val = 0;
508 else
509 val -= right_step;
510
426 reg &= ~TWL6040_HF_VOL_MASK; 511 reg &= ~TWL6040_HF_VOL_MASK;
427 twl6040_write(codec, TWL6040_REG_HFRGAIN, 512 twl6040_write(codec, TWL6040_REG_HFRGAIN,
428 reg | (0x1D - val)); 513 reg | (0x1D - val));
@@ -451,11 +536,9 @@ static void twl6040_pga_hs_work(struct work_struct *work)
451 536
452 /* HS PGA volumes have 4 bits of resolution to ramp */ 537 /* HS PGA volumes have 4 bits of resolution to ramp */
453 for (i = 0; i <= 16; i++) { 538 for (i = 0; i <= 16; i++) {
454 headset_complete = 1; 539 headset_complete = twl6040_hs_ramp_step(codec,
455 if (headset->ramp != TWL6040_RAMP_NONE) 540 headset->left_step,
456 headset_complete = twl6040_hs_ramp_step(codec, 541 headset->right_step);
457 headset->left_step,
458 headset->right_step);
459 542
460 /* ramp finished ? */ 543 /* ramp finished ? */
461 if (headset_complete) 544 if (headset_complete)
@@ -496,11 +579,9 @@ static void twl6040_pga_hf_work(struct work_struct *work)
496 579
497 /* HF PGA volumes have 5 bits of resolution to ramp */ 580 /* HF PGA volumes have 5 bits of resolution to ramp */
498 for (i = 0; i <= 32; i++) { 581 for (i = 0; i <= 32; i++) {
499 handsfree_complete = 1; 582 handsfree_complete = twl6040_hf_ramp_step(codec,
500 if (handsfree->ramp != TWL6040_RAMP_NONE) 583 handsfree->left_step,
501 handsfree_complete = twl6040_hf_ramp_step(codec, 584 handsfree->right_step);
502 handsfree->left_step,
503 handsfree->right_step);
504 585
505 /* ramp finished ? */ 586 /* ramp finished ? */
506 if (handsfree_complete) 587 if (handsfree_complete)
@@ -541,12 +622,16 @@ static int pga_event(struct snd_soc_dapm_widget *w,
541 out = &priv->headset; 622 out = &priv->headset;
542 work = &priv->hs_delayed_work; 623 work = &priv->hs_delayed_work;
543 queue = priv->hs_workqueue; 624 queue = priv->hs_workqueue;
625 out->left_step = priv->hs_left_step;
626 out->right_step = priv->hs_right_step;
544 out->step_delay = 5; /* 5 ms between volume ramp steps */ 627 out->step_delay = 5; /* 5 ms between volume ramp steps */
545 break; 628 break;
546 case 4: 629 case 4:
547 out = &priv->handsfree; 630 out = &priv->handsfree;
548 work = &priv->hf_delayed_work; 631 work = &priv->hf_delayed_work;
549 queue = priv->hf_workqueue; 632 queue = priv->hf_workqueue;
633 out->left_step = priv->hf_left_step;
634 out->right_step = priv->hf_right_step;
550 out->step_delay = 5; /* 5 ms between volume ramp steps */ 635 out->step_delay = 5; /* 5 ms between volume ramp steps */
551 if (SND_SOC_DAPM_EVENT_ON(event)) 636 if (SND_SOC_DAPM_EVENT_ON(event))
552 priv->non_lp++; 637 priv->non_lp++;
@@ -579,8 +664,6 @@ static int pga_event(struct snd_soc_dapm_widget *w,
579 664
580 if (!delayed_work_pending(work)) { 665 if (!delayed_work_pending(work)) {
581 /* use volume ramp for power-down */ 666 /* use volume ramp for power-down */
582 out->left_step = 1;
583 out->right_step = 1;
584 out->ramp = TWL6040_RAMP_DOWN; 667 out->ramp = TWL6040_RAMP_DOWN;
585 INIT_COMPLETION(out->ramp_done); 668 INIT_COMPLETION(out->ramp_done);
586 669
@@ -596,88 +679,6 @@ static int pga_event(struct snd_soc_dapm_widget *w,
596 return 0; 679 return 0;
597} 680}
598 681
599/* twl6040 codec manual power-up sequence */
600static void twl6040_power_up(struct snd_soc_codec *codec)
601{
602 u8 ncpctl, ldoctl, lppllctl, accctl;
603
604 ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
605 ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
606 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
607 accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
608
609 /* enable reference system */
610 ldoctl |= TWL6040_REFENA;
611 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
612 msleep(10);
613 /* enable internal oscillator */
614 ldoctl |= TWL6040_OSCENA;
615 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
616 udelay(10);
617 /* enable high-side ldo */
618 ldoctl |= TWL6040_HSLDOENA;
619 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
620 udelay(244);
621 /* enable negative charge pump */
622 ncpctl |= TWL6040_NCPENA | TWL6040_NCPOPEN;
623 twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
624 udelay(488);
625 /* enable low-side ldo */
626 ldoctl |= TWL6040_LSLDOENA;
627 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
628 udelay(244);
629 /* enable low-power pll */
630 lppllctl |= TWL6040_LPLLENA;
631 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
632 /* reset state machine */
633 accctl |= TWL6040_RESETSPLIT;
634 twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
635 mdelay(5);
636 accctl &= ~TWL6040_RESETSPLIT;
637 twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
638 /* disable internal oscillator */
639 ldoctl &= ~TWL6040_OSCENA;
640 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
641}
642
643/* twl6040 codec manual power-down sequence */
644static void twl6040_power_down(struct snd_soc_codec *codec)
645{
646 u8 ncpctl, ldoctl, lppllctl, accctl;
647
648 ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
649 ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
650 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
651 accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
652
653 /* enable internal oscillator */
654 ldoctl |= TWL6040_OSCENA;
655 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
656 udelay(10);
657 /* disable low-power pll */
658 lppllctl &= ~TWL6040_LPLLENA;
659 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
660 /* disable low-side ldo */
661 ldoctl &= ~TWL6040_LSLDOENA;
662 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
663 udelay(244);
664 /* disable negative charge pump */
665 ncpctl &= ~(TWL6040_NCPENA | TWL6040_NCPOPEN);
666 twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
667 udelay(488);
668 /* disable high-side ldo */
669 ldoctl &= ~TWL6040_HSLDOENA;
670 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
671 udelay(244);
672 /* disable internal oscillator */
673 ldoctl &= ~TWL6040_OSCENA;
674 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
675 /* disable reference system */
676 ldoctl &= ~TWL6040_REFENA;
677 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
678 msleep(10);
679}
680
681/* set headset dac and driver power mode */ 682/* set headset dac and driver power mode */
682static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) 683static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
683{ 684{
@@ -713,15 +714,26 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
713{ 714{
714 struct snd_soc_codec *codec = w->codec; 715 struct snd_soc_codec *codec = w->codec;
715 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 716 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
717 int ret = 0;
716 718
717 if (SND_SOC_DAPM_EVENT_ON(event)) 719 if (SND_SOC_DAPM_EVENT_ON(event)) {
718 priv->non_lp++; 720 priv->non_lp++;
719 else 721 if (!strcmp(w->name, "Earphone Driver")) {
722 /* Earphone doesn't support low power mode */
723 priv->hs_power_mode_locked = 1;
724 ret = headset_power_mode(codec, 1);
725 }
726 } else {
720 priv->non_lp--; 727 priv->non_lp--;
728 if (!strcmp(w->name, "Earphone Driver")) {
729 priv->hs_power_mode_locked = 0;
730 ret = headset_power_mode(codec, priv->hs_power_mode);
731 }
732 }
721 733
722 msleep(1); 734 msleep(1);
723 735
724 return 0; 736 return ret;
725} 737}
726 738
727static void twl6040_hs_jack_report(struct snd_soc_codec *codec, 739static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
@@ -766,33 +778,19 @@ static void twl6040_accessory_work(struct work_struct *work)
766} 778}
767 779
768/* audio interrupt handler */ 780/* audio interrupt handler */
769static irqreturn_t twl6040_naudint_handler(int irq, void *data) 781static irqreturn_t twl6040_audio_handler(int irq, void *data)
770{ 782{
771 struct snd_soc_codec *codec = data; 783 struct snd_soc_codec *codec = data;
784 struct twl6040 *twl6040 = codec->control_data;
772 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 785 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
773 u8 intid; 786 u8 intid;
774 787
775 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID); 788 intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
776
777 if (intid & TWL6040_THINT)
778 dev_alert(codec->dev, "die temp over-limit detection\n");
779 789
780 if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT)) 790 if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT))
781 queue_delayed_work(priv->workqueue, &priv->delayed_work, 791 queue_delayed_work(priv->workqueue, &priv->delayed_work,
782 msecs_to_jiffies(200)); 792 msecs_to_jiffies(200));
783 793
784 if (intid & TWL6040_HOOKINT)
785 dev_info(codec->dev, "hook detection\n");
786
787 if (intid & TWL6040_HFINT)
788 dev_alert(codec->dev, "hf drivers over current detection\n");
789
790 if (intid & TWL6040_VIBINT)
791 dev_alert(codec->dev, "vib drivers over current detection\n");
792
793 if (intid & TWL6040_READYINT)
794 complete(&priv->ready);
795
796 return IRQ_HANDLED; 794 return IRQ_HANDLED;
797} 795}
798 796
@@ -1040,6 +1038,73 @@ static const struct snd_kcontrol_new hfr_mux_controls =
1040static const struct snd_kcontrol_new ep_driver_switch_controls = 1038static const struct snd_kcontrol_new ep_driver_switch_controls =
1041 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); 1039 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
1042 1040
1041/* Headset power mode */
1042static const char *twl6040_power_mode_texts[] = {
1043 "Low-Power", "High-Perfomance",
1044};
1045
1046static const struct soc_enum twl6040_power_mode_enum =
1047 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_power_mode_texts),
1048 twl6040_power_mode_texts);
1049
1050static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
1051 struct snd_ctl_elem_value *ucontrol)
1052{
1053 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1054 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1055
1056 ucontrol->value.enumerated.item[0] = priv->hs_power_mode;
1057
1058 return 0;
1059}
1060
1061static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
1062 struct snd_ctl_elem_value *ucontrol)
1063{
1064 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1065 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1066 int high_perf = ucontrol->value.enumerated.item[0];
1067 int ret = 0;
1068
1069 if (!priv->hs_power_mode_locked)
1070 ret = headset_power_mode(codec, high_perf);
1071
1072 if (!ret)
1073 priv->hs_power_mode = high_perf;
1074
1075 return ret;
1076}
1077
1078static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol,
1079 struct snd_ctl_elem_value *ucontrol)
1080{
1081 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1082 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1083
1084 ucontrol->value.enumerated.item[0] = priv->pll_power_mode;
1085
1086 return 0;
1087}
1088
1089static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol,
1090 struct snd_ctl_elem_value *ucontrol)
1091{
1092 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1093 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1094
1095 priv->pll_power_mode = ucontrol->value.enumerated.item[0];
1096
1097 return 0;
1098}
1099
1100int twl6040_get_clk_id(struct snd_soc_codec *codec)
1101{
1102 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1103
1104 return priv->pll_power_mode;
1105}
1106EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
1107
1043static const struct snd_kcontrol_new twl6040_snd_controls[] = { 1108static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1044 /* Capture gains */ 1109 /* Capture gains */
1045 SOC_DOUBLE_TLV("Capture Preamplifier Volume", 1110 SOC_DOUBLE_TLV("Capture Preamplifier Volume",
@@ -1058,6 +1123,13 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1058 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), 1123 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
1059 SOC_SINGLE_TLV("Earphone Playback Volume", 1124 SOC_SINGLE_TLV("Earphone Playback Volume",
1060 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), 1125 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
1126
1127 SOC_ENUM_EXT("Headset Power Mode", twl6040_power_mode_enum,
1128 twl6040_headset_power_get_enum,
1129 twl6040_headset_power_put_enum),
1130
1131 SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum,
1132 twl6040_pll_get_enum, twl6040_pll_put_enum),
1061}; 1133};
1062 1134
1063static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { 1135static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
@@ -1231,36 +1303,11 @@ static int twl6040_add_widgets(struct snd_soc_codec *codec)
1231 return 0; 1303 return 0;
1232} 1304}
1233 1305
1234static int twl6040_power_up_completion(struct snd_soc_codec *codec,
1235 int naudint)
1236{
1237 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1238 int time_left;
1239 u8 intid;
1240
1241 time_left = wait_for_completion_timeout(&priv->ready,
1242 msecs_to_jiffies(144));
1243
1244 if (!time_left) {
1245 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid,
1246 TWL6040_REG_INTID);
1247 if (!(intid & TWL6040_READYINT)) {
1248 dev_err(codec->dev, "timeout waiting for READYINT\n");
1249 return -ETIMEDOUT;
1250 }
1251 }
1252
1253 priv->codec_powered = 1;
1254
1255 return 0;
1256}
1257
1258static int twl6040_set_bias_level(struct snd_soc_codec *codec, 1306static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1259 enum snd_soc_bias_level level) 1307 enum snd_soc_bias_level level)
1260{ 1308{
1309 struct twl6040 *twl6040 = codec->control_data;
1261 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1310 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1262 int audpwron = priv->audpwron;
1263 int naudint = priv->naudint;
1264 int ret; 1311 int ret;
1265 1312
1266 switch (level) { 1313 switch (level) {
@@ -1272,58 +1319,23 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1272 if (priv->codec_powered) 1319 if (priv->codec_powered)
1273 break; 1320 break;
1274 1321
1275 if (gpio_is_valid(audpwron)) { 1322 ret = twl6040_power(twl6040, 1);
1276 /* use AUDPWRON line */ 1323 if (ret)
1277 gpio_set_value(audpwron, 1); 1324 return ret;
1278 1325
1279 /* wait for power-up completion */ 1326 priv->codec_powered = 1;
1280 ret = twl6040_power_up_completion(codec, naudint);
1281 if (ret)
1282 return ret;
1283
1284 /* sync registers updated during power-up sequence */
1285 twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
1286 twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
1287 twl6040_read_reg_volatile(codec, TWL6040_REG_LPPLLCTL);
1288 } else {
1289 /* use manual power-up sequence */
1290 twl6040_power_up(codec);
1291 priv->codec_powered = 1;
1292 }
1293 1327
1294 /* initialize vdd/vss registers with reg_cache */ 1328 /* initialize vdd/vss registers with reg_cache */
1295 twl6040_init_vdd_regs(codec); 1329 twl6040_init_vdd_regs(codec);
1296 1330
1297 /* Set external boost GPO */ 1331 /* Set external boost GPO */
1298 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); 1332 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
1299
1300 /* Set initial minimal gain values */
1301 twl6040_write(codec, TWL6040_REG_HSGAIN, 0xFF);
1302 twl6040_write(codec, TWL6040_REG_EARCTL, 0x1E);
1303 twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1D);
1304 twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1D);
1305 break; 1333 break;
1306 case SND_SOC_BIAS_OFF: 1334 case SND_SOC_BIAS_OFF:
1307 if (!priv->codec_powered) 1335 if (!priv->codec_powered)
1308 break; 1336 break;
1309 1337
1310 if (gpio_is_valid(audpwron)) { 1338 twl6040_power(twl6040, 0);
1311 /* use AUDPWRON line */
1312 gpio_set_value(audpwron, 0);
1313
1314 /* power-down sequence latency */
1315 udelay(500);
1316
1317 /* sync registers updated during power-down sequence */
1318 twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
1319 twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
1320 twl6040_write_reg_cache(codec, TWL6040_REG_LPPLLCTL,
1321 0x00);
1322 } else {
1323 /* use manual power-down sequence */
1324 twl6040_power_down(codec);
1325 }
1326
1327 priv->codec_powered = 0; 1339 priv->codec_powered = 0;
1328 break; 1340 break;
1329 } 1341 }
@@ -1333,27 +1345,6 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1333 return 0; 1345 return 0;
1334} 1346}
1335 1347
1336/* set of rates for each pll: low-power and high-performance */
1337
1338static unsigned int lp_rates[] = {
1339 88200,
1340 96000,
1341};
1342
1343static struct snd_pcm_hw_constraint_list lp_constraints = {
1344 .count = ARRAY_SIZE(lp_rates),
1345 .list = lp_rates,
1346};
1347
1348static unsigned int hp_rates[] = {
1349 96000,
1350};
1351
1352static struct snd_pcm_hw_constraint_list hp_constraints = {
1353 .count = ARRAY_SIZE(hp_rates),
1354 .list = hp_rates,
1355};
1356
1357static int twl6040_startup(struct snd_pcm_substream *substream, 1348static int twl6040_startup(struct snd_pcm_substream *substream,
1358 struct snd_soc_dai *dai) 1349 struct snd_soc_dai *dai)
1359{ 1350{
@@ -1363,7 +1354,7 @@ static int twl6040_startup(struct snd_pcm_substream *substream,
1363 1354
1364 snd_pcm_hw_constraint_list(substream->runtime, 0, 1355 snd_pcm_hw_constraint_list(substream->runtime, 0,
1365 SNDRV_PCM_HW_PARAM_RATE, 1356 SNDRV_PCM_HW_PARAM_RATE,
1366 priv->sysclk_constraints); 1357 &sysclk_constraints[priv->pll_power_mode]);
1367 1358
1368 return 0; 1359 return 0;
1369} 1360}
@@ -1375,22 +1366,27 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1375 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1366 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1376 struct snd_soc_codec *codec = rtd->codec; 1367 struct snd_soc_codec *codec = rtd->codec;
1377 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1368 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1378 u8 lppllctl;
1379 int rate; 1369 int rate;
1380 1370
1381 /* nothing to do for high-perf pll, it supports only 48 kHz */
1382 if (priv->pll == TWL6040_HPPLL_ID)
1383 return 0;
1384
1385 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
1386
1387 rate = params_rate(params); 1371 rate = params_rate(params);
1388 switch (rate) { 1372 switch (rate) {
1389 case 11250: 1373 case 11250:
1390 case 22500: 1374 case 22500:
1391 case 44100: 1375 case 44100:
1392 case 88200: 1376 case 88200:
1393 lppllctl |= TWL6040_LPLLFIN; 1377 /* These rates are not supported when HPPLL is in use */
1378 if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) {
1379 dev_err(codec->dev, "HPPLL does not support rate %d\n",
1380 rate);
1381 return -EINVAL;
1382 }
1383 /* Capture is not supported with 17.64MHz sysclk */
1384 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
1385 dev_err(codec->dev,
1386 "capture mode is not supported at %dHz\n",
1387 rate);
1388 return -EINVAL;
1389 }
1394 priv->sysclk = 17640000; 1390 priv->sysclk = 17640000;
1395 break; 1391 break;
1396 case 8000: 1392 case 8000:
@@ -1398,7 +1394,6 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1398 case 32000: 1394 case 32000:
1399 case 48000: 1395 case 48000:
1400 case 96000: 1396 case 96000:
1401 lppllctl &= ~TWL6040_LPLLFIN;
1402 priv->sysclk = 19200000; 1397 priv->sysclk = 19200000;
1403 break; 1398 break;
1404 default: 1399 default:
@@ -1406,8 +1401,6 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1406 return -EINVAL; 1401 return -EINVAL;
1407 } 1402 }
1408 1403
1409 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1410
1411 return 0; 1404 return 0;
1412} 1405}
1413 1406
@@ -1416,7 +1409,9 @@ static int twl6040_prepare(struct snd_pcm_substream *substream,
1416{ 1409{
1417 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1410 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1418 struct snd_soc_codec *codec = rtd->codec; 1411 struct snd_soc_codec *codec = rtd->codec;
1412 struct twl6040 *twl6040 = codec->control_data;
1419 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1413 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1414 int ret;
1420 1415
1421 if (!priv->sysclk) { 1416 if (!priv->sysclk) {
1422 dev_err(codec->dev, 1417 dev_err(codec->dev,
@@ -1424,24 +1419,19 @@ static int twl6040_prepare(struct snd_pcm_substream *substream,
1424 return -EINVAL; 1419 return -EINVAL;
1425 } 1420 }
1426 1421
1427 /*
1428 * capture is not supported at 17.64 MHz,
1429 * it's reserved for headset low-power playback scenario
1430 */
1431 if ((priv->sysclk == 17640000) &&
1432 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
1433 dev_err(codec->dev,
1434 "capture mode is not supported at %dHz\n",
1435 priv->sysclk);
1436 return -EINVAL;
1437 }
1438
1439 if ((priv->sysclk == 17640000) && priv->non_lp) { 1422 if ((priv->sysclk == 17640000) && priv->non_lp) {
1440 dev_err(codec->dev, 1423 dev_err(codec->dev,
1441 "some enabled paths aren't supported at %dHz\n", 1424 "some enabled paths aren't supported at %dHz\n",
1442 priv->sysclk); 1425 priv->sysclk);
1443 return -EPERM; 1426 return -EPERM;
1444 } 1427 }
1428
1429 ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk);
1430 if (ret) {
1431 dev_err(codec->dev, "Can not set PLL (%d)\n", ret);
1432 return -EPERM;
1433 }
1434
1445 return 0; 1435 return 0;
1446} 1436}
1447 1437
@@ -1450,99 +1440,12 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1450{ 1440{
1451 struct snd_soc_codec *codec = codec_dai->codec; 1441 struct snd_soc_codec *codec = codec_dai->codec;
1452 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1442 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1453 u8 hppllctl, lppllctl;
1454
1455 hppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_HPPLLCTL);
1456 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
1457 1443
1458 switch (clk_id) { 1444 switch (clk_id) {
1459 case TWL6040_SYSCLK_SEL_LPPLL: 1445 case TWL6040_SYSCLK_SEL_LPPLL:
1460 switch (freq) {
1461 case 32768:
1462 /* headset dac and driver must be in low-power mode */
1463 headset_power_mode(codec, 0);
1464
1465 /* clk32k input requires low-power pll */
1466 lppllctl |= TWL6040_LPLLENA;
1467 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1468 mdelay(5);
1469 lppllctl &= ~TWL6040_HPLLSEL;
1470 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1471 hppllctl &= ~TWL6040_HPLLENA;
1472 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
1473 break;
1474 default:
1475 dev_err(codec->dev, "unknown mclk freq %d\n", freq);
1476 return -EINVAL;
1477 }
1478
1479 /* lppll divider */
1480 switch (priv->sysclk) {
1481 case 17640000:
1482 lppllctl |= TWL6040_LPLLFIN;
1483 break;
1484 case 19200000:
1485 lppllctl &= ~TWL6040_LPLLFIN;
1486 break;
1487 default:
1488 /* sysclk not yet configured */
1489 lppllctl &= ~TWL6040_LPLLFIN;
1490 priv->sysclk = 19200000;
1491 break;
1492 }
1493
1494 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1495
1496 priv->pll = TWL6040_LPPLL_ID;
1497 priv->sysclk_constraints = &lp_constraints;
1498 break;
1499 case TWL6040_SYSCLK_SEL_HPPLL: 1446 case TWL6040_SYSCLK_SEL_HPPLL:
1500 hppllctl &= ~TWL6040_MCLK_MSK; 1447 priv->pll = clk_id;
1501 1448 priv->clk_in = freq;
1502 switch (freq) {
1503 case 12000000:
1504 /* mclk input, pll enabled */
1505 hppllctl |= TWL6040_MCLK_12000KHZ |
1506 TWL6040_HPLLSQRBP |
1507 TWL6040_HPLLENA;
1508 break;
1509 case 19200000:
1510 /* mclk input, pll disabled */
1511 hppllctl |= TWL6040_MCLK_19200KHZ |
1512 TWL6040_HPLLSQRENA |
1513 TWL6040_HPLLBP;
1514 break;
1515 case 26000000:
1516 /* mclk input, pll enabled */
1517 hppllctl |= TWL6040_MCLK_26000KHZ |
1518 TWL6040_HPLLSQRBP |
1519 TWL6040_HPLLENA;
1520 break;
1521 case 38400000:
1522 /* clk slicer, pll disabled */
1523 hppllctl |= TWL6040_MCLK_38400KHZ |
1524 TWL6040_HPLLSQRENA |
1525 TWL6040_HPLLBP;
1526 break;
1527 default:
1528 dev_err(codec->dev, "unknown mclk freq %d\n", freq);
1529 return -EINVAL;
1530 }
1531
1532 /* headset dac and driver must be in high-performance mode */
1533 headset_power_mode(codec, 1);
1534
1535 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
1536 udelay(500);
1537 lppllctl |= TWL6040_HPLLSEL;
1538 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1539 lppllctl &= ~TWL6040_LPLLENA;
1540 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1541
1542 /* high-performance pll can provide only 19.2 MHz */
1543 priv->pll = TWL6040_HPPLL_ID;
1544 priv->sysclk = 19200000;
1545 priv->sysclk_constraints = &hp_constraints;
1546 break; 1449 break;
1547 default: 1450 default:
1548 dev_err(codec->dev, "unknown clk_id %d\n", clk_id); 1451 dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
@@ -1559,15 +1462,27 @@ static struct snd_soc_dai_ops twl6040_dai_ops = {
1559 .set_sysclk = twl6040_set_dai_sysclk, 1462 .set_sysclk = twl6040_set_dai_sysclk,
1560}; 1463};
1561 1464
1562static struct snd_soc_dai_driver twl6040_dai = { 1465static struct snd_soc_dai_driver twl6040_dai[] = {
1466{
1563 .name = "twl6040-hifi", 1467 .name = "twl6040-hifi",
1564 .playback = { 1468 .playback = {
1565 .stream_name = "Playback", 1469 .stream_name = "Playback",
1566 .channels_min = 1, 1470 .channels_min = 1,
1567 .channels_max = 4, 1471 .channels_max = 2,
1472 .rates = TWL6040_RATES,
1473 .formats = TWL6040_FORMATS,
1474 },
1475 .capture = {
1476 .stream_name = "Capture",
1477 .channels_min = 1,
1478 .channels_max = 2,
1568 .rates = TWL6040_RATES, 1479 .rates = TWL6040_RATES,
1569 .formats = TWL6040_FORMATS, 1480 .formats = TWL6040_FORMATS,
1570 }, 1481 },
1482 .ops = &twl6040_dai_ops,
1483},
1484{
1485 .name = "twl6040-ul",
1571 .capture = { 1486 .capture = {
1572 .stream_name = "Capture", 1487 .stream_name = "Capture",
1573 .channels_min = 1, 1488 .channels_min = 1,
@@ -1576,6 +1491,40 @@ static struct snd_soc_dai_driver twl6040_dai = {
1576 .formats = TWL6040_FORMATS, 1491 .formats = TWL6040_FORMATS,
1577 }, 1492 },
1578 .ops = &twl6040_dai_ops, 1493 .ops = &twl6040_dai_ops,
1494},
1495{
1496 .name = "twl6040-dl1",
1497 .playback = {
1498 .stream_name = "Headset Playback",
1499 .channels_min = 1,
1500 .channels_max = 2,
1501 .rates = TWL6040_RATES,
1502 .formats = TWL6040_FORMATS,
1503 },
1504 .ops = &twl6040_dai_ops,
1505},
1506{
1507 .name = "twl6040-dl2",
1508 .playback = {
1509 .stream_name = "Handsfree Playback",
1510 .channels_min = 1,
1511 .channels_max = 2,
1512 .rates = TWL6040_RATES,
1513 .formats = TWL6040_FORMATS,
1514 },
1515 .ops = &twl6040_dai_ops,
1516},
1517{
1518 .name = "twl6040-vib",
1519 .playback = {
1520 .stream_name = "Vibra Playback",
1521 .channels_min = 2,
1522 .channels_max = 2,
1523 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1524 .formats = TWL6040_FORMATS,
1525 },
1526 .ops = &twl6040_dai_ops,
1527},
1579}; 1528};
1580 1529
1581#ifdef CONFIG_PM 1530#ifdef CONFIG_PM
@@ -1600,11 +1549,11 @@ static int twl6040_resume(struct snd_soc_codec *codec)
1600 1549
1601static int twl6040_probe(struct snd_soc_codec *codec) 1550static int twl6040_probe(struct snd_soc_codec *codec)
1602{ 1551{
1603 struct twl4030_codec_data *twl_codec = codec->dev->platform_data;
1604 struct twl6040_data *priv; 1552 struct twl6040_data *priv;
1605 int audpwron, naudint; 1553 struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
1554 struct platform_device *pdev = container_of(codec->dev,
1555 struct platform_device, dev);
1606 int ret = 0; 1556 int ret = 0;
1607 u8 icrev, intmr = TWL6040_ALLINT_MSK;
1608 1557
1609 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); 1558 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
1610 if (priv == NULL) 1559 if (priv == NULL)
@@ -1612,23 +1561,32 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1612 snd_soc_codec_set_drvdata(codec, priv); 1561 snd_soc_codec_set_drvdata(codec, priv);
1613 1562
1614 priv->codec = codec; 1563 priv->codec = codec;
1564 codec->control_data = dev_get_drvdata(codec->dev->parent);
1615 1565
1616 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &icrev, TWL6040_REG_ASICREV); 1566 if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
1567 priv->hs_left_step = pdata->hs_left_step;
1568 priv->hs_right_step = pdata->hs_right_step;
1569 } else {
1570 priv->hs_left_step = 1;
1571 priv->hs_right_step = 1;
1572 }
1617 1573
1618 if (twl_codec && (icrev > 0)) 1574 if (pdata && pdata->hf_left_step && pdata->hf_right_step) {
1619 audpwron = twl_codec->audpwron_gpio; 1575 priv->hf_left_step = pdata->hf_left_step;
1620 else 1576 priv->hf_right_step = pdata->hf_right_step;
1621 audpwron = -EINVAL; 1577 } else {
1578 priv->hf_left_step = 1;
1579 priv->hf_right_step = 1;
1580 }
1622 1581
1623 if (twl_codec) 1582 priv->plug_irq = platform_get_irq(pdev, 0);
1624 naudint = twl_codec->naudint_irq; 1583 if (priv->plug_irq < 0) {
1625 else 1584 dev_err(codec->dev, "invalid irq\n");
1626 naudint = 0; 1585 ret = -EINVAL;
1586 goto work_err;
1587 }
1627 1588
1628 priv->audpwron = audpwron;
1629 priv->naudint = naudint;
1630 priv->workqueue = create_singlethread_workqueue("twl6040-codec"); 1589 priv->workqueue = create_singlethread_workqueue("twl6040-codec");
1631
1632 if (!priv->workqueue) { 1590 if (!priv->workqueue) {
1633 ret = -ENOMEM; 1591 ret = -ENOMEM;
1634 goto work_err; 1592 goto work_err;
@@ -1638,56 +1596,33 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1638 1596
1639 mutex_init(&priv->mutex); 1597 mutex_init(&priv->mutex);
1640 1598
1641 init_completion(&priv->ready);
1642 init_completion(&priv->headset.ramp_done); 1599 init_completion(&priv->headset.ramp_done);
1643 init_completion(&priv->handsfree.ramp_done); 1600 init_completion(&priv->handsfree.ramp_done);
1644 1601
1645 if (gpio_is_valid(audpwron)) {
1646 ret = gpio_request(audpwron, "audpwron");
1647 if (ret)
1648 goto gpio1_err;
1649
1650 ret = gpio_direction_output(audpwron, 0);
1651 if (ret)
1652 goto gpio2_err;
1653
1654 priv->codec_powered = 0;
1655
1656 /* enable only codec ready interrupt */
1657 intmr &= ~(TWL6040_READYMSK | TWL6040_PLUGMSK);
1658
1659 /* reset interrupt status to allow correct power up sequence */
1660 twl6040_read_reg_volatile(codec, TWL6040_REG_INTID);
1661 }
1662 twl6040_write(codec, TWL6040_REG_INTMR, intmr);
1663
1664 if (naudint) {
1665 /* audio interrupt */
1666 ret = request_threaded_irq(naudint, NULL,
1667 twl6040_naudint_handler,
1668 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1669 "twl6040_codec", codec);
1670 if (ret)
1671 goto gpio2_err;
1672 }
1673
1674 /* init vio registers */
1675 twl6040_init_vio_regs(codec);
1676
1677 priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf"); 1602 priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf");
1678 if (priv->hf_workqueue == NULL) { 1603 if (priv->hf_workqueue == NULL) {
1679 ret = -ENOMEM; 1604 ret = -ENOMEM;
1680 goto irq_err; 1605 goto hfwq_err;
1681 } 1606 }
1682 priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs"); 1607 priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs");
1683 if (priv->hs_workqueue == NULL) { 1608 if (priv->hs_workqueue == NULL) {
1684 ret = -ENOMEM; 1609 ret = -ENOMEM;
1685 goto wq_err; 1610 goto hswq_err;
1686 } 1611 }
1687 1612
1688 INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work); 1613 INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work);
1689 INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work); 1614 INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work);
1690 1615
1616 ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler,
1617 0, "twl6040_irq_plug", codec);
1618 if (ret) {
1619 dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret);
1620 goto plugirq_err;
1621 }
1622
1623 /* init vio registers */
1624 twl6040_init_vio_regs(codec);
1625
1691 /* power on device */ 1626 /* power on device */
1692 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1627 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1693 if (ret) 1628 if (ret)
@@ -1700,16 +1635,12 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1700 return 0; 1635 return 0;
1701 1636
1702bias_err: 1637bias_err:
1638 free_irq(priv->plug_irq, codec);
1639plugirq_err:
1703 destroy_workqueue(priv->hs_workqueue); 1640 destroy_workqueue(priv->hs_workqueue);
1704wq_err: 1641hswq_err:
1705 destroy_workqueue(priv->hf_workqueue); 1642 destroy_workqueue(priv->hf_workqueue);
1706irq_err: 1643hfwq_err:
1707 if (naudint)
1708 free_irq(naudint, codec);
1709gpio2_err:
1710 if (gpio_is_valid(audpwron))
1711 gpio_free(audpwron);
1712gpio1_err:
1713 destroy_workqueue(priv->workqueue); 1644 destroy_workqueue(priv->workqueue);
1714work_err: 1645work_err:
1715 kfree(priv); 1646 kfree(priv);
@@ -1719,17 +1650,9 @@ work_err:
1719static int twl6040_remove(struct snd_soc_codec *codec) 1650static int twl6040_remove(struct snd_soc_codec *codec)
1720{ 1651{
1721 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1652 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1722 int audpwron = priv->audpwron;
1723 int naudint = priv->naudint;
1724 1653
1725 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); 1654 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1726 1655 free_irq(priv->plug_irq, codec);
1727 if (gpio_is_valid(audpwron))
1728 gpio_free(audpwron);
1729
1730 if (naudint)
1731 free_irq(naudint, codec);
1732
1733 destroy_workqueue(priv->workqueue); 1656 destroy_workqueue(priv->workqueue);
1734 destroy_workqueue(priv->hf_workqueue); 1657 destroy_workqueue(priv->hf_workqueue);
1735 destroy_workqueue(priv->hs_workqueue); 1658 destroy_workqueue(priv->hs_workqueue);
@@ -1753,8 +1676,8 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1753 1676
1754static int __devinit twl6040_codec_probe(struct platform_device *pdev) 1677static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1755{ 1678{
1756 return snd_soc_register_codec(&pdev->dev, 1679 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040,
1757 &soc_codec_dev_twl6040, &twl6040_dai, 1); 1680 twl6040_dai, ARRAY_SIZE(twl6040_dai));
1758} 1681}
1759 1682
1760static int __devexit twl6040_codec_remove(struct platform_device *pdev) 1683static int __devexit twl6040_codec_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index 23aeed0963e6..d8de67869dd9 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -22,125 +22,8 @@
22#ifndef __TWL6040_H__ 22#ifndef __TWL6040_H__
23#define __TWL6040_H__ 23#define __TWL6040_H__
24 24
25#define TWL6040_REG_ASICID 0x01
26#define TWL6040_REG_ASICREV 0x02
27#define TWL6040_REG_INTID 0x03
28#define TWL6040_REG_INTMR 0x04
29#define TWL6040_REG_NCPCTL 0x05
30#define TWL6040_REG_LDOCTL 0x06
31#define TWL6040_REG_HPPLLCTL 0x07
32#define TWL6040_REG_LPPLLCTL 0x08
33#define TWL6040_REG_LPPLLDIV 0x09
34#define TWL6040_REG_AMICBCTL 0x0A
35#define TWL6040_REG_DMICBCTL 0x0B
36#define TWL6040_REG_MICLCTL 0x0C
37#define TWL6040_REG_MICRCTL 0x0D
38#define TWL6040_REG_MICGAIN 0x0E
39#define TWL6040_REG_LINEGAIN 0x0F
40#define TWL6040_REG_HSLCTL 0x10
41#define TWL6040_REG_HSRCTL 0x11
42#define TWL6040_REG_HSGAIN 0x12
43#define TWL6040_REG_EARCTL 0x13
44#define TWL6040_REG_HFLCTL 0x14
45#define TWL6040_REG_HFLGAIN 0x15
46#define TWL6040_REG_HFRCTL 0x16
47#define TWL6040_REG_HFRGAIN 0x17
48#define TWL6040_REG_VIBCTLL 0x18
49#define TWL6040_REG_VIBDATL 0x19
50#define TWL6040_REG_VIBCTLR 0x1A
51#define TWL6040_REG_VIBDATR 0x1B
52#define TWL6040_REG_HKCTL1 0x1C
53#define TWL6040_REG_HKCTL2 0x1D
54#define TWL6040_REG_GPOCTL 0x1E
55#define TWL6040_REG_ALB 0x1F
56#define TWL6040_REG_DLB 0x20
57#define TWL6040_REG_TRIM1 0x28
58#define TWL6040_REG_TRIM2 0x29
59#define TWL6040_REG_TRIM3 0x2A
60#define TWL6040_REG_HSOTRIM 0x2B
61#define TWL6040_REG_HFOTRIM 0x2C
62#define TWL6040_REG_ACCCTL 0x2D
63#define TWL6040_REG_STATUS 0x2E
64
65#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1)
66
67#define TWL6040_VIOREGNUM 18
68#define TWL6040_VDDREGNUM 21
69
70/* INTID (0x03) fields */
71
72#define TWL6040_THINT 0x01
73#define TWL6040_PLUGINT 0x02
74#define TWL6040_UNPLUGINT 0x04
75#define TWL6040_HOOKINT 0x08
76#define TWL6040_HFINT 0x10
77#define TWL6040_VIBINT 0x20
78#define TWL6040_READYINT 0x40
79
80/* INTMR (0x04) fields */
81
82#define TWL6040_PLUGMSK 0x02
83#define TWL6040_READYMSK 0x40
84#define TWL6040_ALLINT_MSK 0x7B
85
86/* NCPCTL (0x05) fields */
87
88#define TWL6040_NCPENA 0x01
89#define TWL6040_NCPOPEN 0x40
90
91/* LDOCTL (0x06) fields */
92
93#define TWL6040_LSLDOENA 0x01
94#define TWL6040_HSLDOENA 0x04
95#define TWL6040_REFENA 0x40
96#define TWL6040_OSCENA 0x80
97
98/* HPPLLCTL (0x07) fields */
99
100#define TWL6040_HPLLENA 0x01
101#define TWL6040_HPLLRST 0x02
102#define TWL6040_HPLLBP 0x04
103#define TWL6040_HPLLSQRENA 0x08
104#define TWL6040_HPLLSQRBP 0x10
105#define TWL6040_MCLK_12000KHZ (0 << 5)
106#define TWL6040_MCLK_19200KHZ (1 << 5)
107#define TWL6040_MCLK_26000KHZ (2 << 5)
108#define TWL6040_MCLK_38400KHZ (3 << 5)
109#define TWL6040_MCLK_MSK 0x60
110
111/* LPPLLCTL (0x08) fields */
112
113#define TWL6040_LPLLENA 0x01
114#define TWL6040_LPLLRST 0x02
115#define TWL6040_LPLLSEL 0x04
116#define TWL6040_LPLLFIN 0x08
117#define TWL6040_HPLLSEL 0x10
118
119/* HSLCTL (0x10) fields */
120
121#define TWL6040_HSDACMODEL 0x02
122#define TWL6040_HSDRVMODEL 0x08
123
124/* HSRCTL (0x11) fields */
125
126#define TWL6040_HSDACMODER 0x02
127#define TWL6040_HSDRVMODER 0x08
128
129/* ACCCTL (0x2D) fields */
130
131#define TWL6040_RESETSPLIT 0x04
132
133#define TWL6040_SYSCLK_SEL_LPPLL 1
134#define TWL6040_SYSCLK_SEL_HPPLL 2
135
136#define TWL6040_HPPLL_ID 1
137#define TWL6040_LPPLL_ID 2
138
139/* STATUS (0x2E) fields */
140
141#define TWL6040_PLUGCOMP 0x02
142
143void twl6040_hs_jack_detect(struct snd_soc_codec *codec, 25void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
144 struct snd_soc_jack *jack, int report); 26 struct snd_soc_jack *jack, int report);
27int twl6040_get_clk_id(struct snd_soc_codec *codec);
145 28
146#endif /* End of __TWL6040_H__ */ 29#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index 104e95cda0ad..c7417c76552b 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -106,12 +106,12 @@ static struct ep93xx_ac97_info *ep93xx_ac97_info;
106 106
107static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = { 107static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = {
108 .name = "ac97-pcm-out", 108 .name = "ac97-pcm-out",
109 .dma_port = EP93XX_DMA_M2P_PORT_AAC1, 109 .dma_port = EP93XX_DMA_AAC1,
110}; 110};
111 111
112static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = { 112static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = {
113 .name = "ac97-pcm-in", 113 .name = "ac97-pcm-in",
114 .dma_port = EP93XX_DMA_M2P_PORT_AAC1, 114 .dma_port = EP93XX_DMA_AAC1,
115}; 115};
116 116
117static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info, 117static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info,
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 042f4e93746f..56efa0c1c9a9 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -2,7 +2,7 @@
2 * linux/sound/soc/ep93xx-i2s.c 2 * linux/sound/soc/ep93xx-i2s.c
3 * EP93xx I2S driver 3 * EP93xx I2S driver
4 * 4 *
5 * Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.com> 5 * Copyright (C) 2010 Ryan Mallon
6 * 6 *
7 * Based on the original driver by: 7 * Based on the original driver by:
8 * Copyright (C) 2007 Chase Douglas <chasedouglas@gmail> 8 * Copyright (C) 2007 Chase Douglas <chasedouglas@gmail>
@@ -70,11 +70,11 @@ struct ep93xx_i2s_info {
70struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = { 70struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = {
71 [SNDRV_PCM_STREAM_PLAYBACK] = { 71 [SNDRV_PCM_STREAM_PLAYBACK] = {
72 .name = "i2s-pcm-out", 72 .name = "i2s-pcm-out",
73 .dma_port = EP93XX_DMA_M2P_PORT_I2S1, 73 .dma_port = EP93XX_DMA_I2S1,
74 }, 74 },
75 [SNDRV_PCM_STREAM_CAPTURE] = { 75 [SNDRV_PCM_STREAM_CAPTURE] = {
76 .name = "i2s-pcm-in", 76 .name = "i2s-pcm-in",
77 .dma_port = EP93XX_DMA_M2P_PORT_I2S1, 77 .dma_port = EP93XX_DMA_I2S1,
78 }, 78 },
79}; 79};
80 80
@@ -477,6 +477,6 @@ module_init(ep93xx_i2s_init);
477module_exit(ep93xx_i2s_exit); 477module_exit(ep93xx_i2s_exit);
478 478
479MODULE_ALIAS("platform:ep93xx-i2s"); 479MODULE_ALIAS("platform:ep93xx-i2s");
480MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com>"); 480MODULE_AUTHOR("Ryan Mallon");
481MODULE_DESCRIPTION("EP93XX I2S driver"); 481MODULE_DESCRIPTION("EP93XX I2S driver");
482MODULE_LICENSE("GPL"); 482MODULE_LICENSE("GPL");
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index e27c417da437..8dfd3ad84b19 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -5,7 +5,7 @@
5 * Copyright (C) 2006 Applied Data Systems 5 * Copyright (C) 2006 Applied Data Systems
6 * 6 *
7 * Rewritten for the SoC audio subsystem (Based on PXA2xx code): 7 * Rewritten for the SoC audio subsystem (Based on PXA2xx code):
8 * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com> 8 * Copyright (c) 2008 Ryan Mallon
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/dmaengine.h>
19#include <linux/dma-mapping.h> 20#include <linux/dma-mapping.h>
20 21
21#include <sound/core.h> 22#include <sound/core.h>
@@ -53,43 +54,34 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
53 54
54struct ep93xx_runtime_data 55struct ep93xx_runtime_data
55{ 56{
56 struct ep93xx_dma_m2p_client cl;
57 struct ep93xx_pcm_dma_params *params;
58 int pointer_bytes; 57 int pointer_bytes;
59 struct tasklet_struct period_tasklet;
60 int periods; 58 int periods;
61 struct ep93xx_dma_buffer buf[32]; 59 int period_bytes;
60 struct dma_chan *dma_chan;
61 struct ep93xx_dma_data dma_data;
62}; 62};
63 63
64static void ep93xx_pcm_period_elapsed(unsigned long data) 64static void ep93xx_pcm_dma_callback(void *data)
65{ 65{
66 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data; 66 struct snd_pcm_substream *substream = data;
67 snd_pcm_period_elapsed(substream); 67 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
68}
69 68
70static void ep93xx_pcm_buffer_started(void *cookie, 69 rtd->pointer_bytes += rtd->period_bytes;
71 struct ep93xx_dma_buffer *buf) 70 rtd->pointer_bytes %= rtd->period_bytes * rtd->periods;
72{ 71
72 snd_pcm_period_elapsed(substream);
73} 73}
74 74
75static void ep93xx_pcm_buffer_finished(void *cookie, 75static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
76 struct ep93xx_dma_buffer *buf,
77 int bytes, int error)
78{ 76{
79 struct snd_pcm_substream *substream = cookie; 77 struct ep93xx_dma_data *data = filter_param;
80 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
81
82 if (buf == rtd->buf + rtd->periods - 1)
83 rtd->pointer_bytes = 0;
84 else
85 rtd->pointer_bytes += buf->size;
86 78
87 if (!error) { 79 if (data->direction == ep93xx_dma_chan_direction(chan)) {
88 ep93xx_dma_m2p_submit_recursive(&rtd->cl, buf); 80 chan->private = data;
89 tasklet_schedule(&rtd->period_tasklet); 81 return true;
90 } else {
91 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
92 } 82 }
83
84 return false;
93} 85}
94 86
95static int ep93xx_pcm_open(struct snd_pcm_substream *substream) 87static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
@@ -98,30 +90,38 @@ static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
98 struct snd_soc_dai *cpu_dai = soc_rtd->cpu_dai; 90 struct snd_soc_dai *cpu_dai = soc_rtd->cpu_dai;
99 struct ep93xx_pcm_dma_params *dma_params; 91 struct ep93xx_pcm_dma_params *dma_params;
100 struct ep93xx_runtime_data *rtd; 92 struct ep93xx_runtime_data *rtd;
93 dma_cap_mask_t mask;
101 int ret; 94 int ret;
102 95
103 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); 96 ret = snd_pcm_hw_constraint_integer(substream->runtime,
97 SNDRV_PCM_HW_PARAM_PERIODS);
98 if (ret < 0)
99 return ret;
100
104 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); 101 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
105 102
106 rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); 103 rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
107 if (!rtd) 104 if (!rtd)
108 return -ENOMEM; 105 return -ENOMEM;
109 106
110 memset(&rtd->period_tasklet, 0, sizeof(rtd->period_tasklet)); 107 dma_cap_zero(mask);
111 rtd->period_tasklet.func = ep93xx_pcm_period_elapsed; 108 dma_cap_set(DMA_SLAVE, mask);
112 rtd->period_tasklet.data = (unsigned long)substream; 109 dma_cap_set(DMA_CYCLIC, mask);
113 110
114 rtd->cl.name = dma_params->name; 111 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream);
115 rtd->cl.flags = dma_params->dma_port | EP93XX_DMA_M2P_IGNORE_ERROR | 112 rtd->dma_data.port = dma_params->dma_port;
116 ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 113 rtd->dma_data.name = dma_params->name;
117 EP93XX_DMA_M2P_TX : EP93XX_DMA_M2P_RX); 114
118 rtd->cl.cookie = substream; 115 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
119 rtd->cl.buffer_started = ep93xx_pcm_buffer_started; 116 rtd->dma_data.direction = DMA_TO_DEVICE;
120 rtd->cl.buffer_finished = ep93xx_pcm_buffer_finished; 117 else
121 ret = ep93xx_dma_m2p_client_register(&rtd->cl); 118 rtd->dma_data.direction = DMA_FROM_DEVICE;
122 if (ret < 0) { 119
120 rtd->dma_chan = dma_request_channel(mask, ep93xx_pcm_dma_filter,
121 &rtd->dma_data);
122 if (!rtd->dma_chan) {
123 kfree(rtd); 123 kfree(rtd);
124 return ret; 124 return -EINVAL;
125 } 125 }
126 126
127 substream->runtime->private_data = rtd; 127 substream->runtime->private_data = rtd;
@@ -132,31 +132,52 @@ static int ep93xx_pcm_close(struct snd_pcm_substream *substream)
132{ 132{
133 struct ep93xx_runtime_data *rtd = substream->runtime->private_data; 133 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
134 134
135 ep93xx_dma_m2p_client_unregister(&rtd->cl); 135 dma_release_channel(rtd->dma_chan);
136 kfree(rtd); 136 kfree(rtd);
137 return 0; 137 return 0;
138} 138}
139 139
140static int ep93xx_pcm_dma_submit(struct snd_pcm_substream *substream)
141{
142 struct snd_pcm_runtime *runtime = substream->runtime;
143 struct ep93xx_runtime_data *rtd = runtime->private_data;
144 struct dma_chan *chan = rtd->dma_chan;
145 struct dma_device *dma_dev = chan->device;
146 struct dma_async_tx_descriptor *desc;
147
148 rtd->pointer_bytes = 0;
149 desc = dma_dev->device_prep_dma_cyclic(chan, runtime->dma_addr,
150 rtd->period_bytes * rtd->periods,
151 rtd->period_bytes,
152 rtd->dma_data.direction);
153 if (!desc)
154 return -EINVAL;
155
156 desc->callback = ep93xx_pcm_dma_callback;
157 desc->callback_param = substream;
158
159 dmaengine_submit(desc);
160 return 0;
161}
162
163static void ep93xx_pcm_dma_flush(struct snd_pcm_substream *substream)
164{
165 struct snd_pcm_runtime *runtime = substream->runtime;
166 struct ep93xx_runtime_data *rtd = runtime->private_data;
167
168 dmaengine_terminate_all(rtd->dma_chan);
169}
170
140static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, 171static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
141 struct snd_pcm_hw_params *params) 172 struct snd_pcm_hw_params *params)
142{ 173{
143 struct snd_pcm_runtime *runtime = substream->runtime; 174 struct snd_pcm_runtime *runtime = substream->runtime;
144 struct ep93xx_runtime_data *rtd = runtime->private_data; 175 struct ep93xx_runtime_data *rtd = runtime->private_data;
145 size_t totsize = params_buffer_bytes(params);
146 size_t period = params_period_bytes(params);
147 int i;
148 176
149 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 177 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
150 runtime->dma_bytes = totsize;
151
152 rtd->periods = (totsize + period - 1) / period;
153 for (i = 0; i < rtd->periods; i++) {
154 rtd->buf[i].bus_addr = runtime->dma_addr + (i * period);
155 rtd->buf[i].size = period;
156 if ((i + 1) * period > totsize)
157 rtd->buf[i].size = totsize - (i * period);
158 }
159 178
179 rtd->periods = params_periods(params);
180 rtd->period_bytes = params_period_bytes(params);
160 return 0; 181 return 0;
161} 182}
162 183
@@ -168,24 +189,20 @@ static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream)
168 189
169static int ep93xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 190static int ep93xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
170{ 191{
171 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
172 int ret; 192 int ret;
173 int i;
174 193
175 ret = 0; 194 ret = 0;
176 switch (cmd) { 195 switch (cmd) {
177 case SNDRV_PCM_TRIGGER_START: 196 case SNDRV_PCM_TRIGGER_START:
178 case SNDRV_PCM_TRIGGER_RESUME: 197 case SNDRV_PCM_TRIGGER_RESUME:
179 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 198 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
180 rtd->pointer_bytes = 0; 199 ret = ep93xx_pcm_dma_submit(substream);
181 for (i = 0; i < rtd->periods; i++)
182 ep93xx_dma_m2p_submit(&rtd->cl, rtd->buf + i);
183 break; 200 break;
184 201
185 case SNDRV_PCM_TRIGGER_STOP: 202 case SNDRV_PCM_TRIGGER_STOP:
186 case SNDRV_PCM_TRIGGER_SUSPEND: 203 case SNDRV_PCM_TRIGGER_SUSPEND:
187 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 204 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
188 ep93xx_dma_m2p_flush(&rtd->cl); 205 ep93xx_pcm_dma_flush(substream);
189 break; 206 break;
190 207
191 default: 208 default:
@@ -335,6 +352,6 @@ static void __exit ep93xx_soc_platform_exit(void)
335module_init(ep93xx_soc_platform_init); 352module_init(ep93xx_soc_platform_init);
336module_exit(ep93xx_soc_platform_exit); 353module_exit(ep93xx_soc_platform_exit);
337 354
338MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com>"); 355MODULE_AUTHOR("Ryan Mallon");
339MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); 356MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
340MODULE_LICENSE("GPL"); 357MODULE_LICENSE("GPL");
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index dfe1d7f74ea6..c8aa8a5003ca 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -2,7 +2,7 @@
2 * snappercl15.c -- SoC audio for Bluewater Systems Snapper CL15 module 2 * snappercl15.c -- SoC audio for Bluewater Systems Snapper CL15 module
3 * 3 *
4 * Copyright (C) 2008 Bluewater Systems Ltd 4 * Copyright (C) 2008 Bluewater Systems Ltd
5 * Author: Ryan Mallon <ryan@bluewatersys.com> 5 * Author: Ryan Mallon
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 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 8 * under the terms of the GNU General Public License as published by the
@@ -140,7 +140,7 @@ static void __exit snappercl15_exit(void)
140module_init(snappercl15_init); 140module_init(snappercl15_init);
141module_exit(snappercl15_exit); 141module_exit(snappercl15_exit);
142 142
143MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com>"); 143MODULE_AUTHOR("Ryan Mallon");
144MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); 144MODULE_DESCRIPTION("ALSA SoC Snapper CL15");
145MODULE_LICENSE("GPL"); 145MODULE_LICENSE("GPL");
146 146
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 19ad0c1be67e..fd0dc46afc34 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -385,7 +385,7 @@ static int mpc5200_hpcd_probe(struct of_device *op)
385 dev_err(&op->dev, "Missing reg property\n"); 385 dev_err(&op->dev, "Missing reg property\n");
386 return -ENODEV; 386 return -ENODEV;
387 } 387 }
388 regs = ioremap(res.start, 1 + res.end - res.start); 388 regs = ioremap(res.start, resource_size(&res));
389 if (!regs) { 389 if (!regs) {
390 dev_err(&op->dev, "Could not map registers\n"); 390 dev_err(&op->dev, "Could not map registers\n");
391 return -ENODEV; 391 return -ENODEV;
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 4173b3d87f97..43fdc24f7e8d 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -110,12 +110,12 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
110 slave_config.direction = DMA_TO_DEVICE; 110 slave_config.direction = DMA_TO_DEVICE;
111 slave_config.dst_addr = dma_params->dma_addr; 111 slave_config.dst_addr = dma_params->dma_addr;
112 slave_config.dst_addr_width = buswidth; 112 slave_config.dst_addr_width = buswidth;
113 slave_config.dst_maxburst = dma_params->burstsize * buswidth; 113 slave_config.dst_maxburst = dma_params->burstsize;
114 } else { 114 } else {
115 slave_config.direction = DMA_FROM_DEVICE; 115 slave_config.direction = DMA_FROM_DEVICE;
116 slave_config.src_addr = dma_params->dma_addr; 116 slave_config.src_addr = dma_params->dma_addr;
117 slave_config.src_addr_width = buswidth; 117 slave_config.src_addr_width = buswidth;
118 slave_config.src_maxburst = dma_params->burstsize * buswidth; 118 slave_config.src_maxburst = dma_params->burstsize;
119 } 119 }
120 120
121 ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); 121 ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config);
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index b40095a19883..30fe0d0efe1c 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -330,7 +330,7 @@ static int cx81801_hangup(struct tty_struct *tty)
330 return 0; 330 return 0;
331} 331}
332 332
333/* Line discipline .recieve_buf() */ 333/* Line discipline .receive_buf() */
334static void cx81801_receive(struct tty_struct *tty, 334static void cx81801_receive(struct tty_struct *tty,
335 const unsigned char *cp, char *fp, int count) 335 const unsigned char *cp, char *fp, int count)
336{ 336{
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 3f72d17d1ef0..9f6a758029d1 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -36,7 +36,7 @@
36#include <plat/mcbsp.h> 36#include <plat/mcbsp.h>
37 37
38/* Register descriptions for twl4030 codec part */ 38/* Register descriptions for twl4030 codec part */
39#include <linux/mfd/twl4030-codec.h> 39#include <linux/mfd/twl4030-audio.h>
40 40
41#include "omap-mcbsp.h" 41#include "omap-mcbsp.h"
42#include "omap-pcm.h" 42#include "omap-pcm.h"
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 189e03900637..b80efb02bfca 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -21,6 +21,8 @@
21 21
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/mfd/twl6040.h>
25
24#include <sound/core.h> 26#include <sound/core.h>
25#include <sound/pcm.h> 27#include <sound/pcm.h>
26#include <sound/soc.h> 28#include <sound/soc.h>
@@ -34,8 +36,6 @@
34#include "omap-pcm.h" 36#include "omap-pcm.h"
35#include "../codecs/twl6040.h" 37#include "../codecs/twl6040.h"
36 38
37static int twl6040_power_mode;
38
39static int sdp4430_hw_params(struct snd_pcm_substream *substream, 39static int sdp4430_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params) 40 struct snd_pcm_hw_params *params)
41{ 41{
@@ -44,13 +44,13 @@ static int sdp4430_hw_params(struct snd_pcm_substream *substream,
44 int clk_id, freq; 44 int clk_id, freq;
45 int ret; 45 int ret;
46 46
47 if (twl6040_power_mode) { 47 clk_id = twl6040_get_clk_id(rtd->codec);
48 clk_id = TWL6040_SYSCLK_SEL_HPPLL; 48 if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
49 freq = 38400000; 49 freq = 38400000;
50 } else { 50 else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
51 clk_id = TWL6040_SYSCLK_SEL_LPPLL;
52 freq = 32768; 51 freq = 32768;
53 } 52 else
53 return -EINVAL;
54 54
55 /* set the codec mclk */ 55 /* set the codec mclk */
56 ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq, 56 ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
@@ -81,35 +81,6 @@ static struct snd_soc_jack_pin hs_jack_pins[] = {
81 }, 81 },
82}; 82};
83 83
84static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol,
85 struct snd_ctl_elem_value *ucontrol)
86{
87 ucontrol->value.integer.value[0] = twl6040_power_mode;
88 return 0;
89}
90
91static int sdp4430_set_power_mode(struct snd_kcontrol *kcontrol,
92 struct snd_ctl_elem_value *ucontrol)
93{
94 if (twl6040_power_mode == ucontrol->value.integer.value[0])
95 return 0;
96
97 twl6040_power_mode = ucontrol->value.integer.value[0];
98
99 return 1;
100}
101
102static const char *power_texts[] = {"Low-Power", "High-Performance"};
103
104static const struct soc_enum sdp4430_enum[] = {
105 SOC_ENUM_SINGLE_EXT(2, power_texts),
106};
107
108static const struct snd_kcontrol_new sdp4430_controls[] = {
109 SOC_ENUM_EXT("TWL6040 Power Mode", sdp4430_enum[0],
110 sdp4430_get_power_mode, sdp4430_set_power_mode),
111};
112
113/* SDP4430 machine DAPM */ 84/* SDP4430 machine DAPM */
114static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { 85static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
115 SND_SOC_DAPM_MIC("Ext Mic", NULL), 86 SND_SOC_DAPM_MIC("Ext Mic", NULL),
@@ -152,12 +123,6 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
152 struct snd_soc_dapm_context *dapm = &codec->dapm; 123 struct snd_soc_dapm_context *dapm = &codec->dapm;
153 int ret; 124 int ret;
154 125
155 /* Add SDP4430 specific controls */
156 ret = snd_soc_add_controls(codec, sdp4430_controls,
157 ARRAY_SIZE(sdp4430_controls));
158 if (ret)
159 return ret;
160
161 /* Add SDP4430 specific widgets */ 126 /* Add SDP4430 specific widgets */
162 ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets, 127 ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets,
163 ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); 128 ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
@@ -237,9 +202,6 @@ static int __init sdp4430_soc_init(void)
237 if (ret) 202 if (ret)
238 goto err; 203 goto err;
239 204
240 /* Codec starts in HP mode */
241 twl6040_power_mode = 1;
242
243 return 0; 205 return 0;
244 206
245err: 207err:
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 01709940a43c..9a2666ffc16c 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -32,7 +32,7 @@
32#include <plat/mcbsp.h> 32#include <plat/mcbsp.h>
33 33
34/* Register descriptions for twl4030 codec part */ 34/* Register descriptions for twl4030 codec part */
35#include <linux/mfd/twl4030-codec.h> 35#include <linux/mfd/twl4030-audio.h>
36 36
37#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
38#include "omap-pcm.h" 38#include "omap-pcm.h"
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 73f9cbacc077..1b839a0f3653 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -69,7 +69,7 @@
69 69
70#include <linux/of.h> 70#include <linux/of.h>
71#include <linux/of_device.h> 71#include <linux/of_device.h>
72#include <asm/atomic.h> 72#include <linux/atomic.h>
73 73
74MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets"); 74MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
75MODULE_DESCRIPTION("Sun DBRI"); 75MODULE_DESCRIPTION("Sun DBRI");