diff options
Diffstat (limited to 'sound')
164 files changed, 3153 insertions, 1778 deletions
diff --git a/sound/aoa/core/alsa.c b/sound/aoa/core/alsa.c index 617850463582..0fa3855b4790 100644 --- a/sound/aoa/core/alsa.c +++ b/sound/aoa/core/alsa.c | |||
@@ -23,9 +23,10 @@ int aoa_alsa_init(char *name, struct module *mod, struct device *dev) | |||
23 | /* cannot be EEXIST due to usage in aoa_fabric_register */ | 23 | /* cannot be EEXIST due to usage in aoa_fabric_register */ |
24 | return -EBUSY; | 24 | return -EBUSY; |
25 | 25 | ||
26 | alsa_card = snd_card_new(index, name, mod, sizeof(struct aoa_card)); | 26 | err = snd_card_create(index, name, mod, sizeof(struct aoa_card), |
27 | if (!alsa_card) | 27 | &alsa_card); |
28 | return -ENOMEM; | 28 | if (err < 0) |
29 | return err; | ||
29 | aoa_card = alsa_card->private_data; | 30 | aoa_card = alsa_card->private_data; |
30 | aoa_card->alsa_card = alsa_card; | 31 | aoa_card->alsa_card = alsa_card; |
31 | alsa_card->dev = dev; | 32 | alsa_card->dev = dev; |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 89096e811a4b..7d39aac9ec14 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -995,10 +995,11 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) | |||
995 | { | 995 | { |
996 | struct aaci *aaci; | 996 | struct aaci *aaci; |
997 | struct snd_card *card; | 997 | struct snd_card *card; |
998 | int err; | ||
998 | 999 | ||
999 | card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | 1000 | err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, |
1000 | THIS_MODULE, sizeof(struct aaci)); | 1001 | THIS_MODULE, sizeof(struct aaci), &card); |
1001 | if (card == NULL) | 1002 | if (err < 0) |
1002 | return NULL; | 1003 | return NULL; |
1003 | 1004 | ||
1004 | card->private_free = aaci_free_card; | 1005 | card->private_free = aaci_free_card; |
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 85cf591d4e11..7ed100c80a5f 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c | |||
@@ -173,10 +173,9 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) | |||
173 | struct snd_ac97_template ac97_template; | 173 | struct snd_ac97_template ac97_template; |
174 | int ret; | 174 | int ret; |
175 | 175 | ||
176 | ret = -ENOMEM; | 176 | ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, |
177 | card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | 177 | THIS_MODULE, 0, &card); |
178 | THIS_MODULE, 0); | 178 | if (ret < 0) |
179 | if (!card) | ||
180 | goto err; | 179 | goto err; |
181 | 180 | ||
182 | card->dev = &dev->dev; | 181 | card->dev = &dev->dev; |
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c index 1dcd51d81d10..51d708c31e65 100644 --- a/sound/arm/sa11xx-uda1341.c +++ b/sound/arm/sa11xx-uda1341.c | |||
@@ -887,9 +887,10 @@ static int __devinit sa11xx_uda1341_probe(struct platform_device *devptr) | |||
887 | struct sa11xx_uda1341 *chip; | 887 | struct sa11xx_uda1341 *chip; |
888 | 888 | ||
889 | /* register the soundcard */ | 889 | /* register the soundcard */ |
890 | card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct sa11xx_uda1341)); | 890 | err = snd_card_create(-1, id, THIS_MODULE, |
891 | if (card == NULL) | 891 | sizeof(struct sa11xx_uda1341), &card); |
892 | return -ENOMEM; | 892 | if (err < 0) |
893 | return err; | ||
893 | 894 | ||
894 | chip = card->private_data; | 895 | chip = card->private_data; |
895 | spin_lock_init(&chip->s[0].dma_lock); | 896 | spin_lock_init(&chip->s[0].dma_lock); |
diff --git a/sound/core/init.c b/sound/core/init.c index 0d5520c415d3..dc4b80c7f311 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -121,31 +121,44 @@ static inline int init_info_for_card(struct snd_card *card) | |||
121 | #endif | 121 | #endif |
122 | 122 | ||
123 | /** | 123 | /** |
124 | * snd_card_new - create and initialize a soundcard structure | 124 | * snd_card_create - create and initialize a soundcard structure |
125 | * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] | 125 | * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] |
126 | * @xid: card identification (ASCII string) | 126 | * @xid: card identification (ASCII string) |
127 | * @module: top level module for locking | 127 | * @module: top level module for locking |
128 | * @extra_size: allocate this extra size after the main soundcard structure | 128 | * @extra_size: allocate this extra size after the main soundcard structure |
129 | * @card_ret: the pointer to store the created card instance | ||
129 | * | 130 | * |
130 | * Creates and initializes a soundcard structure. | 131 | * Creates and initializes a soundcard structure. |
131 | * | 132 | * |
132 | * Returns kmallocated snd_card structure. Creates the ALSA control interface | 133 | * The function allocates snd_card instance via kzalloc with the given |
133 | * (which is blocked until snd_card_register function is called). | 134 | * space for the driver to use freely. The allocated struct is stored |
135 | * in the given card_ret pointer. | ||
136 | * | ||
137 | * Returns zero if successful or a negative error code. | ||
134 | */ | 138 | */ |
135 | struct snd_card *snd_card_new(int idx, const char *xid, | 139 | int snd_card_create(int idx, const char *xid, |
136 | struct module *module, int extra_size) | 140 | struct module *module, int extra_size, |
141 | struct snd_card **card_ret) | ||
137 | { | 142 | { |
138 | struct snd_card *card; | 143 | struct snd_card *card; |
139 | int err, idx2; | 144 | int err, idx2; |
140 | 145 | ||
146 | if (snd_BUG_ON(!card_ret)) | ||
147 | return -EINVAL; | ||
148 | *card_ret = NULL; | ||
149 | |||
141 | if (extra_size < 0) | 150 | if (extra_size < 0) |
142 | extra_size = 0; | 151 | extra_size = 0; |
143 | card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL); | 152 | card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL); |
144 | if (card == NULL) | 153 | if (!card) |
145 | return NULL; | 154 | return -ENOMEM; |
146 | if (xid) { | 155 | if (xid) { |
147 | if (!snd_info_check_reserved_words(xid)) | 156 | if (!snd_info_check_reserved_words(xid)) { |
157 | snd_printk(KERN_ERR | ||
158 | "given id string '%s' is reserved.\n", xid); | ||
159 | err = -EBUSY; | ||
148 | goto __error; | 160 | goto __error; |
161 | } | ||
149 | strlcpy(card->id, xid, sizeof(card->id)); | 162 | strlcpy(card->id, xid, sizeof(card->id)); |
150 | } | 163 | } |
151 | err = 0; | 164 | err = 0; |
@@ -202,26 +215,28 @@ struct snd_card *snd_card_new(int idx, const char *xid, | |||
202 | #endif | 215 | #endif |
203 | /* the control interface cannot be accessed from the user space until */ | 216 | /* the control interface cannot be accessed from the user space until */ |
204 | /* snd_cards_bitmask and snd_cards are set with snd_card_register */ | 217 | /* snd_cards_bitmask and snd_cards are set with snd_card_register */ |
205 | if ((err = snd_ctl_create(card)) < 0) { | 218 | err = snd_ctl_create(card); |
206 | snd_printd("unable to register control minors\n"); | 219 | if (err < 0) { |
220 | snd_printk(KERN_ERR "unable to register control minors\n"); | ||
207 | goto __error; | 221 | goto __error; |
208 | } | 222 | } |
209 | if ((err = snd_info_card_create(card)) < 0) { | 223 | err = snd_info_card_create(card); |
210 | snd_printd("unable to create card info\n"); | 224 | if (err < 0) { |
225 | snd_printk(KERN_ERR "unable to create card info\n"); | ||
211 | goto __error_ctl; | 226 | goto __error_ctl; |
212 | } | 227 | } |
213 | if (extra_size > 0) | 228 | if (extra_size > 0) |
214 | card->private_data = (char *)card + sizeof(struct snd_card); | 229 | card->private_data = (char *)card + sizeof(struct snd_card); |
215 | return card; | 230 | *card_ret = card; |
231 | return 0; | ||
216 | 232 | ||
217 | __error_ctl: | 233 | __error_ctl: |
218 | snd_device_free_all(card, SNDRV_DEV_CMD_PRE); | 234 | snd_device_free_all(card, SNDRV_DEV_CMD_PRE); |
219 | __error: | 235 | __error: |
220 | kfree(card); | 236 | kfree(card); |
221 | return NULL; | 237 | return err; |
222 | } | 238 | } |
223 | 239 | EXPORT_SYMBOL(snd_card_create); | |
224 | EXPORT_SYMBOL(snd_card_new); | ||
225 | 240 | ||
226 | /* return non-zero if a card is already locked */ | 241 | /* return non-zero if a card is already locked */ |
227 | int snd_card_locked(int card) | 242 | int snd_card_locked(int card) |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 73be7e14a603..54239d2e0997 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -588,10 +588,10 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr) | |||
588 | int idx, err; | 588 | int idx, err; |
589 | int dev = devptr->id; | 589 | int dev = devptr->id; |
590 | 590 | ||
591 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 591 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
592 | sizeof(struct snd_dummy)); | 592 | sizeof(struct snd_dummy), &card); |
593 | if (card == NULL) | 593 | if (err < 0) |
594 | return -ENOMEM; | 594 | return err; |
595 | dummy = card->private_data; | 595 | dummy = card->private_data; |
596 | dummy->card = card; | 596 | dummy->card = card; |
597 | for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) { | 597 | for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) { |
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index 7783843ca9ae..1950ffce2b54 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c | |||
@@ -1279,9 +1279,9 @@ static int __devinit snd_ml403_ac97cr_probe(struct platform_device *pfdev) | |||
1279 | if (!enable[dev]) | 1279 | if (!enable[dev]) |
1280 | return -ENOENT; | 1280 | return -ENOENT; |
1281 | 1281 | ||
1282 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1282 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
1283 | if (card == NULL) | 1283 | if (err < 0) |
1284 | return -ENOMEM; | 1284 | return err; |
1285 | err = snd_ml403_ac97cr_create(card, pfdev, &ml403_ac97cr); | 1285 | err = snd_ml403_ac97cr_create(card, pfdev, &ml403_ac97cr); |
1286 | if (err < 0) { | 1286 | if (err < 0) { |
1287 | PDEBUG(INIT_FAILURE, "probe(): create failed!\n"); | 1287 | PDEBUG(INIT_FAILURE, "probe(): create failed!\n"); |
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 5b996f3faba5..149d05a8202d 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c | |||
@@ -73,9 +73,9 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard) | |||
73 | snd_printk(KERN_ERR "the uart_enter option is obsolete; remove it\n"); | 73 | snd_printk(KERN_ERR "the uart_enter option is obsolete; remove it\n"); |
74 | 74 | ||
75 | *rcard = NULL; | 75 | *rcard = NULL; |
76 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 76 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
77 | if (card == NULL) | 77 | if (err < 0) |
78 | return -ENOMEM; | 78 | return err; |
79 | strcpy(card->driver, "MPU-401 UART"); | 79 | strcpy(card->driver, "MPU-401 UART"); |
80 | strcpy(card->shortname, card->driver); | 80 | strcpy(card->shortname, card->driver); |
81 | sprintf(card->longname, "%s at %#lx, ", card->shortname, port[dev]); | 81 | sprintf(card->longname, "%s at %#lx, ", card->shortname, port[dev]); |
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index 5b89c0883d60..c3e9833dcfd9 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c | |||
@@ -696,9 +696,9 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev) | |||
696 | int err; | 696 | int err; |
697 | struct mtpav *mtp_card; | 697 | struct mtpav *mtp_card; |
698 | 698 | ||
699 | card = snd_card_new(index, id, THIS_MODULE, sizeof(*mtp_card)); | 699 | err = snd_card_create(index, id, THIS_MODULE, sizeof(*mtp_card), &card); |
700 | if (! card) | 700 | if (err < 0) |
701 | return -ENOMEM; | 701 | return err; |
702 | 702 | ||
703 | mtp_card = card->private_data; | 703 | mtp_card = card->private_data; |
704 | spin_lock_init(&mtp_card->spinlock); | 704 | spin_lock_init(&mtp_card->spinlock); |
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index 87ba1ddc0115..33d9db782e07 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c | |||
@@ -957,10 +957,10 @@ static int __devinit snd_mts64_probe(struct platform_device *pdev) | |||
957 | if ((err = snd_mts64_probe_port(p)) < 0) | 957 | if ((err = snd_mts64_probe_port(p)) < 0) |
958 | return err; | 958 | return err; |
959 | 959 | ||
960 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 960 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
961 | if (card == NULL) { | 961 | if (err < 0) { |
962 | snd_printd("Cannot create card\n"); | 962 | snd_printd("Cannot create card\n"); |
963 | return -ENOMEM; | 963 | return err; |
964 | } | 964 | } |
965 | strcpy(card->driver, DRIVER_NAME); | 965 | strcpy(card->driver, DRIVER_NAME); |
966 | strcpy(card->shortname, "ESI " CARD_NAME); | 966 | strcpy(card->shortname, "ESI " CARD_NAME); |
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index a4049eb94d35..aa2ae07a76d5 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c | |||
@@ -98,9 +98,9 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev) | |||
98 | hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 98 | hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
99 | pcsp_chip.timer.function = pcsp_do_timer; | 99 | pcsp_chip.timer.function = pcsp_do_timer; |
100 | 100 | ||
101 | card = snd_card_new(index, id, THIS_MODULE, 0); | 101 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
102 | if (!card) | 102 | if (err < 0) |
103 | return -ENOMEM; | 103 | return err; |
104 | 104 | ||
105 | err = snd_pcsp_create(card); | 105 | err = snd_pcsp_create(card); |
106 | if (err < 0) { | 106 | if (err < 0) { |
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c index b1c047ec19af..60158e2e0eaf 100644 --- a/sound/drivers/portman2x4.c +++ b/sound/drivers/portman2x4.c | |||
@@ -746,10 +746,10 @@ static int __devinit snd_portman_probe(struct platform_device *pdev) | |||
746 | if ((err = snd_portman_probe_port(p)) < 0) | 746 | if ((err = snd_portman_probe_port(p)) < 0) |
747 | return err; | 747 | return err; |
748 | 748 | ||
749 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 749 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
750 | if (card == NULL) { | 750 | if (err < 0) { |
751 | snd_printd("Cannot create card\n"); | 751 | snd_printd("Cannot create card\n"); |
752 | return -ENOMEM; | 752 | return err; |
753 | } | 753 | } |
754 | strcpy(card->driver, DRIVER_NAME); | 754 | strcpy(card->driver, DRIVER_NAME); |
755 | strcpy(card->shortname, CARD_NAME); | 755 | strcpy(card->shortname, CARD_NAME); |
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index d8aab9da97c2..891d081e4825 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c | |||
@@ -936,9 +936,9 @@ static int __devinit snd_serial_probe(struct platform_device *devptr) | |||
936 | return -ENODEV; | 936 | return -ENODEV; |
937 | } | 937 | } |
938 | 938 | ||
939 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 939 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
940 | if (card == NULL) | 940 | if (err < 0) |
941 | return -ENOMEM; | 941 | return err; |
942 | 942 | ||
943 | strcpy(card->driver, "Serial"); | 943 | strcpy(card->driver, "Serial"); |
944 | strcpy(card->shortname, "Serial MIDI (UART16550A)"); | 944 | strcpy(card->shortname, "Serial MIDI (UART16550A)"); |
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c index f79e3614079d..6f48711818f3 100644 --- a/sound/drivers/virmidi.c +++ b/sound/drivers/virmidi.c | |||
@@ -90,10 +90,10 @@ static int __devinit snd_virmidi_probe(struct platform_device *devptr) | |||
90 | int idx, err; | 90 | int idx, err; |
91 | int dev = devptr->id; | 91 | int dev = devptr->id; |
92 | 92 | ||
93 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 93 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
94 | sizeof(struct snd_card_virmidi)); | 94 | sizeof(struct snd_card_virmidi), &card); |
95 | if (card == NULL) | 95 | if (err < 0) |
96 | return -ENOMEM; | 96 | return err; |
97 | vmidi = (struct snd_card_virmidi *)card->private_data; | 97 | vmidi = (struct snd_card_virmidi *)card->private_data; |
98 | vmidi->card = card; | 98 | vmidi->card = card; |
99 | 99 | ||
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 77524244a846..9660e598232c 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c | |||
@@ -157,9 +157,10 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard | |||
157 | struct snd_ad1816a *chip; | 157 | struct snd_ad1816a *chip; |
158 | struct snd_opl3 *opl3; | 158 | struct snd_opl3 *opl3; |
159 | 159 | ||
160 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 160 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
161 | sizeof(struct snd_card_ad1816a))) == NULL) | 161 | sizeof(struct snd_card_ad1816a), &card); |
162 | return -ENOMEM; | 162 | if (error < 0) |
163 | return error; | ||
163 | acard = (struct snd_card_ad1816a *)card->private_data; | 164 | acard = (struct snd_card_ad1816a *)card->private_data; |
164 | 165 | ||
165 | if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) { | 166 | if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) { |
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 223a6c038819..4beeb6f98e0e 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c | |||
@@ -91,9 +91,9 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) | |||
91 | struct snd_pcm *pcm; | 91 | struct snd_pcm *pcm; |
92 | int error; | 92 | int error; |
93 | 93 | ||
94 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 94 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
95 | if (!card) | 95 | if (error < 0) |
96 | return -EINVAL; | 96 | return error; |
97 | 97 | ||
98 | error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], -1, | 98 | error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], -1, |
99 | thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT, | 99 | thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT, |
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c index 374b7177e111..7465ae036e0b 100644 --- a/sound/isa/adlib.c +++ b/sound/isa/adlib.c | |||
@@ -53,10 +53,10 @@ static int __devinit snd_adlib_probe(struct device *dev, unsigned int n) | |||
53 | struct snd_opl3 *opl3; | 53 | struct snd_opl3 *opl3; |
54 | int error; | 54 | int error; |
55 | 55 | ||
56 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 56 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
57 | if (!card) { | 57 | if (error < 0) { |
58 | dev_err(dev, "could not create card\n"); | 58 | dev_err(dev, "could not create card\n"); |
59 | return -EINVAL; | 59 | return error; |
60 | } | 60 | } |
61 | 61 | ||
62 | card->private_data = request_region(port[n], 4, CRD_NAME); | 62 | card->private_data = request_region(port[n], 4, CRD_NAME); |
diff --git a/sound/isa/als100.c b/sound/isa/als100.c index f1ce30f379c9..5fd52e4d7079 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c | |||
@@ -163,9 +163,10 @@ static int __devinit snd_card_als100_probe(int dev, | |||
163 | struct snd_card_als100 *acard; | 163 | struct snd_card_als100 *acard; |
164 | struct snd_opl3 *opl3; | 164 | struct snd_opl3 *opl3; |
165 | 165 | ||
166 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 166 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
167 | sizeof(struct snd_card_als100))) == NULL) | 167 | sizeof(struct snd_card_als100), &card); |
168 | return -ENOMEM; | 168 | if (error < 0) |
169 | return error; | ||
169 | acard = card->private_data; | 170 | acard = card->private_data; |
170 | 171 | ||
171 | if ((error = snd_card_als100_pnp(dev, acard, pcard, pid))) { | 172 | if ((error = snd_card_als100_pnp(dev, acard, pcard, pid))) { |
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index 3e74d1a3928e..f7aa637b0d18 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c | |||
@@ -184,9 +184,10 @@ static int __devinit snd_card_azt2320_probe(int dev, | |||
184 | struct snd_wss *chip; | 184 | struct snd_wss *chip; |
185 | struct snd_opl3 *opl3; | 185 | struct snd_opl3 *opl3; |
186 | 186 | ||
187 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 187 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
188 | sizeof(struct snd_card_azt2320))) == NULL) | 188 | sizeof(struct snd_card_azt2320), &card); |
189 | return -ENOMEM; | 189 | if (error < 0) |
190 | return error; | ||
190 | acard = (struct snd_card_azt2320 *)card->private_data; | 191 | acard = (struct snd_card_azt2320 *)card->private_data; |
191 | 192 | ||
192 | if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) { | 193 | if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) { |
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index e49aec700a55..24e60902f8ca 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c | |||
@@ -467,20 +467,22 @@ static int snd_cmi8330_resume(struct snd_card *card) | |||
467 | 467 | ||
468 | #define PFX "cmi8330: " | 468 | #define PFX "cmi8330: " |
469 | 469 | ||
470 | static struct snd_card *snd_cmi8330_card_new(int dev) | 470 | static int snd_cmi8330_card_new(int dev, struct snd_card **cardp) |
471 | { | 471 | { |
472 | struct snd_card *card; | 472 | struct snd_card *card; |
473 | struct snd_cmi8330 *acard; | 473 | struct snd_cmi8330 *acard; |
474 | int err; | ||
474 | 475 | ||
475 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 476 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
476 | sizeof(struct snd_cmi8330)); | 477 | sizeof(struct snd_cmi8330), &card); |
477 | if (card == NULL) { | 478 | if (err < 0) { |
478 | snd_printk(KERN_ERR PFX "could not get a new card\n"); | 479 | snd_printk(KERN_ERR PFX "could not get a new card\n"); |
479 | return NULL; | 480 | return err; |
480 | } | 481 | } |
481 | acard = card->private_data; | 482 | acard = card->private_data; |
482 | acard->card = card; | 483 | acard->card = card; |
483 | return card; | 484 | *cardp = card; |
485 | return 0; | ||
484 | } | 486 | } |
485 | 487 | ||
486 | static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) | 488 | static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) |
@@ -564,9 +566,9 @@ static int __devinit snd_cmi8330_isa_probe(struct device *pdev, | |||
564 | struct snd_card *card; | 566 | struct snd_card *card; |
565 | int err; | 567 | int err; |
566 | 568 | ||
567 | card = snd_cmi8330_card_new(dev); | 569 | err = snd_cmi8330_card_new(dev, &card); |
568 | if (! card) | 570 | if (err < 0) |
569 | return -ENOMEM; | 571 | return err; |
570 | snd_card_set_dev(card, pdev); | 572 | snd_card_set_dev(card, pdev); |
571 | if ((err = snd_cmi8330_probe(card, dev)) < 0) { | 573 | if ((err = snd_cmi8330_probe(card, dev)) < 0) { |
572 | snd_card_free(card); | 574 | snd_card_free(card); |
@@ -628,9 +630,9 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, | |||
628 | if (dev >= SNDRV_CARDS) | 630 | if (dev >= SNDRV_CARDS) |
629 | return -ENODEV; | 631 | return -ENODEV; |
630 | 632 | ||
631 | card = snd_cmi8330_card_new(dev); | 633 | res = snd_cmi8330_card_new(dev, &card); |
632 | if (! card) | 634 | if (res < 0) |
633 | return -ENOMEM; | 635 | return res; |
634 | if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) { | 636 | if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) { |
635 | snd_printk(KERN_ERR PFX "PnP detection failed\n"); | 637 | snd_printk(KERN_ERR PFX "PnP detection failed\n"); |
636 | snd_card_free(card); | 638 | snd_card_free(card); |
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index f019d449e2d6..cb9153e75b82 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c | |||
@@ -95,9 +95,9 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) | |||
95 | struct snd_pcm *pcm; | 95 | struct snd_pcm *pcm; |
96 | int error; | 96 | int error; |
97 | 97 | ||
98 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 98 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
99 | if (!card) | 99 | if (error < 0) |
100 | return -EINVAL; | 100 | return error; |
101 | 101 | ||
102 | error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n], | 102 | error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n], |
103 | WSS_HW_DETECT, 0, &chip); | 103 | WSS_HW_DETECT, 0, &chip); |
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 019c9401663e..f7845986f467 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c | |||
@@ -382,16 +382,18 @@ static void snd_card_cs4236_free(struct snd_card *card) | |||
382 | release_and_free_resource(acard->res_sb_port); | 382 | release_and_free_resource(acard->res_sb_port); |
383 | } | 383 | } |
384 | 384 | ||
385 | static struct snd_card *snd_cs423x_card_new(int dev) | 385 | static int snd_cs423x_card_new(int dev, struct snd_card **cardp) |
386 | { | 386 | { |
387 | struct snd_card *card; | 387 | struct snd_card *card; |
388 | int err; | ||
388 | 389 | ||
389 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 390 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
390 | sizeof(struct snd_card_cs4236)); | 391 | sizeof(struct snd_card_cs4236), &card); |
391 | if (card == NULL) | 392 | if (err < 0) |
392 | return NULL; | 393 | return err; |
393 | card->private_free = snd_card_cs4236_free; | 394 | card->private_free = snd_card_cs4236_free; |
394 | return card; | 395 | *cardp = card; |
396 | return 0; | ||
395 | } | 397 | } |
396 | 398 | ||
397 | static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) | 399 | static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) |
@@ -512,9 +514,9 @@ static int __devinit snd_cs423x_isa_probe(struct device *pdev, | |||
512 | struct snd_card *card; | 514 | struct snd_card *card; |
513 | int err; | 515 | int err; |
514 | 516 | ||
515 | card = snd_cs423x_card_new(dev); | 517 | err = snd_cs423x_card_new(dev, &card); |
516 | if (! card) | 518 | if (err < 0) |
517 | return -ENOMEM; | 519 | return err; |
518 | snd_card_set_dev(card, pdev); | 520 | snd_card_set_dev(card, pdev); |
519 | if ((err = snd_cs423x_probe(card, dev)) < 0) { | 521 | if ((err = snd_cs423x_probe(card, dev)) < 0) { |
520 | snd_card_free(card); | 522 | snd_card_free(card); |
@@ -594,9 +596,9 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | |||
594 | if (dev >= SNDRV_CARDS) | 596 | if (dev >= SNDRV_CARDS) |
595 | return -ENODEV; | 597 | return -ENODEV; |
596 | 598 | ||
597 | card = snd_cs423x_card_new(dev); | 599 | err = snd_cs423x_card_new(dev, &card); |
598 | if (! card) | 600 | if (err < 0) |
599 | return -ENOMEM; | 601 | return err; |
600 | if ((err = snd_card_cs4232_pnp(dev, card->private_data, pdev)) < 0) { | 602 | if ((err = snd_card_cs4232_pnp(dev, card->private_data, pdev)) < 0) { |
601 | printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); | 603 | printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); |
602 | snd_card_free(card); | 604 | snd_card_free(card); |
@@ -656,9 +658,9 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, | |||
656 | if (dev >= SNDRV_CARDS) | 658 | if (dev >= SNDRV_CARDS) |
657 | return -ENODEV; | 659 | return -ENODEV; |
658 | 660 | ||
659 | card = snd_cs423x_card_new(dev); | 661 | res = snd_cs423x_card_new(dev, &card); |
660 | if (! card) | 662 | if (res < 0) |
661 | return -ENOMEM; | 663 | return res; |
662 | if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) { | 664 | if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) { |
663 | printk(KERN_ERR "isapnp detection failed and probing for " IDENT | 665 | printk(KERN_ERR "isapnp detection failed and probing for " IDENT |
664 | " is not supported\n"); | 666 | " is not supported\n"); |
diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c index a0242c3b613e..80f5b1af9be8 100644 --- a/sound/isa/dt019x.c +++ b/sound/isa/dt019x.c | |||
@@ -150,9 +150,10 @@ static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, | |||
150 | struct snd_card_dt019x *acard; | 150 | struct snd_card_dt019x *acard; |
151 | struct snd_opl3 *opl3; | 151 | struct snd_opl3 *opl3; |
152 | 152 | ||
153 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 153 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
154 | sizeof(struct snd_card_dt019x))) == NULL) | 154 | sizeof(struct snd_card_dt019x), &card); |
155 | return -ENOMEM; | 155 | if (error < 0) |
156 | return error; | ||
156 | acard = card->private_data; | 157 | acard = card->private_data; |
157 | 158 | ||
158 | snd_card_set_dev(card, &pcard->card->dev); | 159 | snd_card_set_dev(card, &pcard->card->dev); |
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index b46377139cf8..d746750410ea 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c | |||
@@ -122,9 +122,9 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) | |||
122 | struct snd_pcm *pcm; | 122 | struct snd_pcm *pcm; |
123 | int error; | 123 | int error; |
124 | 124 | ||
125 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 125 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
126 | if (!card) | 126 | if (error < 0) |
127 | return -EINVAL; | 127 | return error; |
128 | 128 | ||
129 | error = snd_es1688_legacy_create(card, dev, n, &chip); | 129 | error = snd_es1688_legacy_create(card, dev, n, &chip); |
130 | if (error < 0) | 130 | if (error < 0) |
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 90498e4ca260..8cfbff73a835 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -2125,10 +2125,10 @@ static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard, | |||
2125 | #define is_isapnp_selected(dev) 0 | 2125 | #define is_isapnp_selected(dev) 0 |
2126 | #endif | 2126 | #endif |
2127 | 2127 | ||
2128 | static struct snd_card *snd_es18xx_card_new(int dev) | 2128 | static int snd_es18xx_card_new(int dev, struct snd_card **cardp) |
2129 | { | 2129 | { |
2130 | return snd_card_new(index[dev], id[dev], THIS_MODULE, | 2130 | return snd_card_create(index[dev], id[dev], THIS_MODULE, |
2131 | sizeof(struct snd_audiodrive)); | 2131 | sizeof(struct snd_audiodrive), cardp); |
2132 | } | 2132 | } |
2133 | 2133 | ||
2134 | static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) | 2134 | static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) |
@@ -2197,9 +2197,9 @@ static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr) | |||
2197 | struct snd_card *card; | 2197 | struct snd_card *card; |
2198 | int err; | 2198 | int err; |
2199 | 2199 | ||
2200 | card = snd_es18xx_card_new(dev); | 2200 | err = snd_es18xx_card_new(dev, &card); |
2201 | if (! card) | 2201 | if (err < 0) |
2202 | return -ENOMEM; | 2202 | return err; |
2203 | snd_card_set_dev(card, devptr); | 2203 | snd_card_set_dev(card, devptr); |
2204 | if ((err = snd_audiodrive_probe(card, dev)) < 0) { | 2204 | if ((err = snd_audiodrive_probe(card, dev)) < 0) { |
2205 | snd_card_free(card); | 2205 | snd_card_free(card); |
@@ -2303,9 +2303,9 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, | |||
2303 | if (dev >= SNDRV_CARDS) | 2303 | if (dev >= SNDRV_CARDS) |
2304 | return -ENODEV; | 2304 | return -ENODEV; |
2305 | 2305 | ||
2306 | card = snd_es18xx_card_new(dev); | 2306 | err = snd_es18xx_card_new(dev, &card); |
2307 | if (! card) | 2307 | if (err < 0) |
2308 | return -ENOMEM; | 2308 | return err; |
2309 | if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) { | 2309 | if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) { |
2310 | snd_card_free(card); | 2310 | snd_card_free(card); |
2311 | return err; | 2311 | return err; |
@@ -2362,9 +2362,9 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard, | |||
2362 | if (dev >= SNDRV_CARDS) | 2362 | if (dev >= SNDRV_CARDS) |
2363 | return -ENODEV; | 2363 | return -ENODEV; |
2364 | 2364 | ||
2365 | card = snd_es18xx_card_new(dev); | 2365 | res = snd_es18xx_card_new(dev, &card); |
2366 | if (! card) | 2366 | if (res < 0) |
2367 | return -ENOMEM; | 2367 | return res; |
2368 | 2368 | ||
2369 | if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) { | 2369 | if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) { |
2370 | snd_card_free(card); | 2370 | snd_card_free(card); |
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 426532a4d730..086b8f0e0f94 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c | |||
@@ -148,9 +148,9 @@ static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n) | |||
148 | struct snd_gus_card *gus; | 148 | struct snd_gus_card *gus; |
149 | int error; | 149 | int error; |
150 | 150 | ||
151 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 151 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
152 | if (!card) | 152 | if (error < 0) |
153 | return -EINVAL; | 153 | return error; |
154 | 154 | ||
155 | if (pcm_channels[n] < 2) | 155 | if (pcm_channels[n] < 2) |
156 | pcm_channels[n] = 2; | 156 | pcm_channels[n] = 2; |
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 7ad4c3b41a84..180a8dea6bd9 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c | |||
@@ -241,9 +241,9 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) | |||
241 | struct snd_opl3 *opl3; | 241 | struct snd_opl3 *opl3; |
242 | int error; | 242 | int error; |
243 | 243 | ||
244 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 244 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
245 | if (!card) | 245 | if (error < 0) |
246 | return -EINVAL; | 246 | return error; |
247 | 247 | ||
248 | if (mpu_port[n] == SNDRV_AUTO_PORT) | 248 | if (mpu_port[n] == SNDRV_AUTO_PORT) |
249 | mpu_port[n] = 0; | 249 | mpu_port[n] = 0; |
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index f94c1976e632..f26eac8d8110 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c | |||
@@ -214,10 +214,10 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) | |||
214 | struct snd_wss *wss; | 214 | struct snd_wss *wss; |
215 | struct snd_gusmax *maxcard; | 215 | struct snd_gusmax *maxcard; |
216 | 216 | ||
217 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 217 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
218 | sizeof(struct snd_gusmax)); | 218 | sizeof(struct snd_gusmax), &card); |
219 | if (card == NULL) | 219 | if (err < 0) |
220 | return -ENOMEM; | 220 | return err; |
221 | card->private_free = snd_gusmax_free; | 221 | card->private_free = snd_gusmax_free; |
222 | maxcard = (struct snd_gusmax *)card->private_data; | 222 | maxcard = (struct snd_gusmax *)card->private_data; |
223 | maxcard->card = card; | 223 | maxcard->card = card; |
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 5faecfb602d3..50e429a120da 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c | |||
@@ -626,20 +626,22 @@ static void snd_interwave_free(struct snd_card *card) | |||
626 | free_irq(iwcard->irq, (void *)iwcard); | 626 | free_irq(iwcard->irq, (void *)iwcard); |
627 | } | 627 | } |
628 | 628 | ||
629 | static struct snd_card *snd_interwave_card_new(int dev) | 629 | static int snd_interwave_card_new(int dev, struct snd_card **cardp) |
630 | { | 630 | { |
631 | struct snd_card *card; | 631 | struct snd_card *card; |
632 | struct snd_interwave *iwcard; | 632 | struct snd_interwave *iwcard; |
633 | int err; | ||
633 | 634 | ||
634 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 635 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
635 | sizeof(struct snd_interwave)); | 636 | sizeof(struct snd_interwave), &card); |
636 | if (card == NULL) | 637 | if (err < 0) |
637 | return NULL; | 638 | return err; |
638 | iwcard = card->private_data; | 639 | iwcard = card->private_data; |
639 | iwcard->card = card; | 640 | iwcard->card = card; |
640 | iwcard->irq = -1; | 641 | iwcard->irq = -1; |
641 | card->private_free = snd_interwave_free; | 642 | card->private_free = snd_interwave_free; |
642 | return card; | 643 | *cardp = card; |
644 | return 0; | ||
643 | } | 645 | } |
644 | 646 | ||
645 | static int __devinit snd_interwave_probe(struct snd_card *card, int dev) | 647 | static int __devinit snd_interwave_probe(struct snd_card *card, int dev) |
@@ -778,9 +780,9 @@ static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr) | |||
778 | struct snd_card *card; | 780 | struct snd_card *card; |
779 | int err; | 781 | int err; |
780 | 782 | ||
781 | card = snd_interwave_card_new(dev); | 783 | err = snd_interwave_card_new(dev, &card); |
782 | if (! card) | 784 | if (err < 0) |
783 | return -ENOMEM; | 785 | return err; |
784 | 786 | ||
785 | snd_card_set_dev(card, devptr); | 787 | snd_card_set_dev(card, devptr); |
786 | if ((err = snd_interwave_probe(card, dev)) < 0) { | 788 | if ((err = snd_interwave_probe(card, dev)) < 0) { |
@@ -876,9 +878,9 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, | |||
876 | if (dev >= SNDRV_CARDS) | 878 | if (dev >= SNDRV_CARDS) |
877 | return -ENODEV; | 879 | return -ENODEV; |
878 | 880 | ||
879 | card = snd_interwave_card_new(dev); | 881 | res = snd_interwave_card_new(dev, &card); |
880 | if (! card) | 882 | if (res < 0) |
881 | return -ENOMEM; | 883 | return res; |
882 | 884 | ||
883 | if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) { | 885 | if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) { |
884 | snd_card_free(card); | 886 | snd_card_free(card); |
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 58c972b2af03..645491a53023 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
@@ -617,21 +617,24 @@ static void snd_opl3sa2_free(struct snd_card *card) | |||
617 | release_and_free_resource(chip->res_port); | 617 | release_and_free_resource(chip->res_port); |
618 | } | 618 | } |
619 | 619 | ||
620 | static struct snd_card *snd_opl3sa2_card_new(int dev) | 620 | static int snd_opl3sa2_card_new(int dev, struct snd_card **cardp) |
621 | { | 621 | { |
622 | struct snd_card *card; | 622 | struct snd_card *card; |
623 | struct snd_opl3sa2 *chip; | 623 | struct snd_opl3sa2 *chip; |
624 | int err; | ||
624 | 625 | ||
625 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_opl3sa2)); | 626 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
626 | if (card == NULL) | 627 | sizeof(struct snd_opl3sa2), &card); |
627 | return NULL; | 628 | if (err < 0) |
629 | return err; | ||
628 | strcpy(card->driver, "OPL3SA2"); | 630 | strcpy(card->driver, "OPL3SA2"); |
629 | strcpy(card->shortname, "Yamaha OPL3-SA2"); | 631 | strcpy(card->shortname, "Yamaha OPL3-SA2"); |
630 | chip = card->private_data; | 632 | chip = card->private_data; |
631 | spin_lock_init(&chip->reg_lock); | 633 | spin_lock_init(&chip->reg_lock); |
632 | chip->irq = -1; | 634 | chip->irq = -1; |
633 | card->private_free = snd_opl3sa2_free; | 635 | card->private_free = snd_opl3sa2_free; |
634 | return card; | 636 | *cardp = card; |
637 | return 0; | ||
635 | } | 638 | } |
636 | 639 | ||
637 | static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) | 640 | static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) |
@@ -723,9 +726,9 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, | |||
723 | if (dev >= SNDRV_CARDS) | 726 | if (dev >= SNDRV_CARDS) |
724 | return -ENODEV; | 727 | return -ENODEV; |
725 | 728 | ||
726 | card = snd_opl3sa2_card_new(dev); | 729 | err = snd_opl3sa2_card_new(dev, &card); |
727 | if (! card) | 730 | if (err < 0) |
728 | return -ENOMEM; | 731 | return err; |
729 | if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { | 732 | if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { |
730 | snd_card_free(card); | 733 | snd_card_free(card); |
731 | return err; | 734 | return err; |
@@ -789,9 +792,9 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard, | |||
789 | if (dev >= SNDRV_CARDS) | 792 | if (dev >= SNDRV_CARDS) |
790 | return -ENODEV; | 793 | return -ENODEV; |
791 | 794 | ||
792 | card = snd_opl3sa2_card_new(dev); | 795 | err = snd_opl3sa2_card_new(dev, &card); |
793 | if (! card) | 796 | if (err < 0) |
794 | return -ENOMEM; | 797 | return err; |
795 | if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { | 798 | if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { |
796 | snd_card_free(card); | 799 | snd_card_free(card); |
797 | return err; | 800 | return err; |
@@ -870,9 +873,9 @@ static int __devinit snd_opl3sa2_isa_probe(struct device *pdev, | |||
870 | struct snd_card *card; | 873 | struct snd_card *card; |
871 | int err; | 874 | int err; |
872 | 875 | ||
873 | card = snd_opl3sa2_card_new(dev); | 876 | err = snd_opl3sa2_card_new(dev, &card); |
874 | if (! card) | 877 | if (err < 0) |
875 | return -ENOMEM; | 878 | return err; |
876 | snd_card_set_dev(card, pdev); | 879 | snd_card_set_dev(card, pdev); |
877 | if ((err = snd_opl3sa2_probe(card, dev)) < 0) { | 880 | if ((err = snd_opl3sa2_probe(card, dev)) < 0) { |
878 | snd_card_free(card); | 881 | snd_card_free(card); |
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 440755cc0013..02e30d7c6a93 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c | |||
@@ -1228,9 +1228,10 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n) | |||
1228 | struct snd_pcm *pcm; | 1228 | struct snd_pcm *pcm; |
1229 | struct snd_rawmidi *rmidi; | 1229 | struct snd_rawmidi *rmidi; |
1230 | 1230 | ||
1231 | if (!(card = snd_card_new(index, id, THIS_MODULE, | 1231 | error = snd_card_create(index, id, THIS_MODULE, |
1232 | sizeof(struct snd_miro)))) | 1232 | sizeof(struct snd_miro), &card); |
1233 | return -ENOMEM; | 1233 | if (error < 0) |
1234 | return error; | ||
1234 | 1235 | ||
1235 | card->private_free = snd_card_miro_free; | 1236 | card->private_free = snd_card_miro_free; |
1236 | miro = card->private_data; | 1237 | miro = card->private_data; |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 19706b0d8497..cd6e60a6a4ea 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -830,15 +830,18 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
830 | return snd_card_register(card); | 830 | return snd_card_register(card); |
831 | } | 831 | } |
832 | 832 | ||
833 | static struct snd_card *snd_opti9xx_card_new(void) | 833 | static int snd_opti9xx_card_new(struct snd_card **cardp) |
834 | { | 834 | { |
835 | struct snd_card *card; | 835 | struct snd_card *card; |
836 | int err; | ||
836 | 837 | ||
837 | card = snd_card_new(index, id, THIS_MODULE, sizeof(struct snd_opti9xx)); | 838 | err = snd_card_create(index, id, THIS_MODULE, |
838 | if (! card) | 839 | sizeof(struct snd_opti9xx), &card); |
839 | return NULL; | 840 | if (err < 0) |
841 | return err; | ||
840 | card->private_free = snd_card_opti9xx_free; | 842 | card->private_free = snd_card_opti9xx_free; |
841 | return card; | 843 | *cardp = card; |
844 | return 0; | ||
842 | } | 845 | } |
843 | 846 | ||
844 | static int __devinit snd_opti9xx_isa_match(struct device *devptr, | 847 | static int __devinit snd_opti9xx_isa_match(struct device *devptr, |
@@ -903,9 +906,9 @@ static int __devinit snd_opti9xx_isa_probe(struct device *devptr, | |||
903 | } | 906 | } |
904 | #endif | 907 | #endif |
905 | 908 | ||
906 | card = snd_opti9xx_card_new(); | 909 | error = snd_opti9xx_card_new(&card); |
907 | if (! card) | 910 | if (error < 0) |
908 | return -ENOMEM; | 911 | return error; |
909 | 912 | ||
910 | if ((error = snd_card_opti9xx_detect(card, card->private_data)) < 0) { | 913 | if ((error = snd_card_opti9xx_detect(card, card->private_data)) < 0) { |
911 | snd_card_free(card); | 914 | snd_card_free(card); |
@@ -950,9 +953,9 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, | |||
950 | return -EBUSY; | 953 | return -EBUSY; |
951 | if (! isapnp) | 954 | if (! isapnp) |
952 | return -ENODEV; | 955 | return -ENODEV; |
953 | card = snd_opti9xx_card_new(); | 956 | error = snd_opti9xx_card_new(&card); |
954 | if (! card) | 957 | if (error < 0) |
955 | return -ENOMEM; | 958 | return error; |
956 | chip = card->private_data; | 959 | chip = card->private_data; |
957 | 960 | ||
958 | hw = snd_card_opti9xx_pnp(chip, pcard, pid); | 961 | hw = snd_card_opti9xx_pnp(chip, pcard, pid); |
diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c index c8c8e214c843..cafc3a7316a8 100644 --- a/sound/isa/sb/es968.c +++ b/sound/isa/sb/es968.c | |||
@@ -108,9 +108,10 @@ static int __devinit snd_card_es968_probe(int dev, | |||
108 | struct snd_card *card; | 108 | struct snd_card *card; |
109 | struct snd_card_es968 *acard; | 109 | struct snd_card_es968 *acard; |
110 | 110 | ||
111 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 111 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
112 | sizeof(struct snd_card_es968))) == NULL) | 112 | sizeof(struct snd_card_es968), &card); |
113 | return -ENOMEM; | 113 | if (error < 0) |
114 | return error; | ||
114 | acard = card->private_data; | 115 | acard = card->private_data; |
115 | if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { | 116 | if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { |
116 | snd_card_free(card); | 117 | snd_card_free(card); |
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 2c201f78ce50..519c36346dec 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c | |||
@@ -324,14 +324,18 @@ static void snd_sb16_free(struct snd_card *card) | |||
324 | #define is_isapnp_selected(dev) 0 | 324 | #define is_isapnp_selected(dev) 0 |
325 | #endif | 325 | #endif |
326 | 326 | ||
327 | static struct snd_card *snd_sb16_card_new(int dev) | 327 | static int snd_sb16_card_new(int dev, struct snd_card **cardp) |
328 | { | 328 | { |
329 | struct snd_card *card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 329 | struct snd_card *card; |
330 | sizeof(struct snd_card_sb16)); | 330 | int err; |
331 | if (card == NULL) | 331 | |
332 | return NULL; | 332 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
333 | sizeof(struct snd_card_sb16), &card); | ||
334 | if (err < 0) | ||
335 | return err; | ||
333 | card->private_free = snd_sb16_free; | 336 | card->private_free = snd_sb16_free; |
334 | return card; | 337 | *cardp = card; |
338 | return 0; | ||
335 | } | 339 | } |
336 | 340 | ||
337 | static int __devinit snd_sb16_probe(struct snd_card *card, int dev) | 341 | static int __devinit snd_sb16_probe(struct snd_card *card, int dev) |
@@ -489,9 +493,9 @@ static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev) | |||
489 | struct snd_card *card; | 493 | struct snd_card *card; |
490 | int err; | 494 | int err; |
491 | 495 | ||
492 | card = snd_sb16_card_new(dev); | 496 | err = snd_sb16_card_new(dev, &card); |
493 | if (! card) | 497 | if (err < 0) |
494 | return -ENOMEM; | 498 | return err; |
495 | 499 | ||
496 | acard = card->private_data; | 500 | acard = card->private_data; |
497 | /* non-PnP FM port address is hardwired with base port address */ | 501 | /* non-PnP FM port address is hardwired with base port address */ |
@@ -610,9 +614,9 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, | |||
610 | for ( ; dev < SNDRV_CARDS; dev++) { | 614 | for ( ; dev < SNDRV_CARDS; dev++) { |
611 | if (!enable[dev] || !isapnp[dev]) | 615 | if (!enable[dev] || !isapnp[dev]) |
612 | continue; | 616 | continue; |
613 | card = snd_sb16_card_new(dev); | 617 | res = snd_sb16_card_new(dev, &card); |
614 | if (! card) | 618 | if (res < 0) |
615 | return -ENOMEM; | 619 | return res; |
616 | snd_card_set_dev(card, &pcard->card->dev); | 620 | snd_card_set_dev(card, &pcard->card->dev); |
617 | if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 || | 621 | if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 || |
618 | (res = snd_sb16_probe(card, dev)) < 0) { | 622 | (res = snd_sb16_probe(card, dev)) < 0) { |
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index ea06877be4b1..3cd57ee54660 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c | |||
@@ -103,10 +103,10 @@ static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev) | |||
103 | struct snd_opl3 *opl3; | 103 | struct snd_opl3 *opl3; |
104 | int err; | 104 | int err; |
105 | 105 | ||
106 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 106 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
107 | sizeof(struct snd_sb8)); | 107 | sizeof(struct snd_sb8), &card); |
108 | if (card == NULL) | 108 | if (err < 0) |
109 | return -ENOMEM; | 109 | return err; |
110 | acard = card->private_data; | 110 | acard = card->private_data; |
111 | card->private_free = snd_sb8_free; | 111 | card->private_free = snd_sb8_free; |
112 | 112 | ||
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index ca35924dc3b3..7a1470376c6d 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c | |||
@@ -489,9 +489,9 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) | |||
489 | char __iomem *vmss_port; | 489 | char __iomem *vmss_port; |
490 | 490 | ||
491 | 491 | ||
492 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 492 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
493 | if (!card) | 493 | if (err < 0) |
494 | return -ENOMEM; | 494 | return err; |
495 | 495 | ||
496 | if (xirq == SNDRV_AUTO_IRQ) { | 496 | if (xirq == SNDRV_AUTO_IRQ) { |
497 | xirq = snd_legacy_find_free_irq(possible_irqs); | 497 | xirq = snd_legacy_find_free_irq(possible_irqs); |
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 2c7503bf1271..6fe27b9d9440 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c | |||
@@ -243,9 +243,9 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) | |||
243 | struct snd_card *card; | 243 | struct snd_card *card; |
244 | struct snd_wss *chip; | 244 | struct snd_wss *chip; |
245 | 245 | ||
246 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 246 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
247 | if (card == NULL) | 247 | if (err < 0) |
248 | return -ENOMEM; | 248 | return err; |
249 | 249 | ||
250 | xirq = irq[dev]; | 250 | xirq = irq[dev]; |
251 | if (xirq == SNDRV_AUTO_IRQ) { | 251 | if (xirq == SNDRV_AUTO_IRQ) { |
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 48a16d865834..4025fb558c50 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -1357,10 +1357,10 @@ static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) | |||
1357 | struct soundscape *sscape; | 1357 | struct soundscape *sscape; |
1358 | int ret; | 1358 | int ret; |
1359 | 1359 | ||
1360 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 1360 | ret = snd_card_create(index[dev], id[dev], THIS_MODULE, |
1361 | sizeof(struct soundscape)); | 1361 | sizeof(struct soundscape), &card); |
1362 | if (!card) | 1362 | if (ret < 0) |
1363 | return -ENOMEM; | 1363 | return ret; |
1364 | 1364 | ||
1365 | sscape = get_card_soundscape(card); | 1365 | sscape = get_card_soundscape(card); |
1366 | sscape->type = SSCAPE; | 1366 | sscape->type = SSCAPE; |
@@ -1462,10 +1462,10 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, | |||
1462 | * Create a new ALSA sound card entry, in anticipation | 1462 | * Create a new ALSA sound card entry, in anticipation |
1463 | * of detecting our hardware ... | 1463 | * of detecting our hardware ... |
1464 | */ | 1464 | */ |
1465 | card = snd_card_new(index[idx], id[idx], THIS_MODULE, | 1465 | ret = snd_card_create(index[idx], id[idx], THIS_MODULE, |
1466 | sizeof(struct soundscape)); | 1466 | sizeof(struct soundscape), &card); |
1467 | if (!card) | 1467 | if (ret < 0) |
1468 | return -ENOMEM; | 1468 | return ret; |
1469 | 1469 | ||
1470 | sscape = get_card_soundscape(card); | 1470 | sscape = get_card_soundscape(card); |
1471 | 1471 | ||
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 4c095bc7c729..95898b2b7b58 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c | |||
@@ -338,15 +338,16 @@ snd_wavefront_free(struct snd_card *card) | |||
338 | } | 338 | } |
339 | } | 339 | } |
340 | 340 | ||
341 | static struct snd_card *snd_wavefront_card_new(int dev) | 341 | static int snd_wavefront_card_new(int dev, struct snd_card **cardp) |
342 | { | 342 | { |
343 | struct snd_card *card; | 343 | struct snd_card *card; |
344 | snd_wavefront_card_t *acard; | 344 | snd_wavefront_card_t *acard; |
345 | int err; | ||
345 | 346 | ||
346 | card = snd_card_new (index[dev], id[dev], THIS_MODULE, | 347 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
347 | sizeof(snd_wavefront_card_t)); | 348 | sizeof(snd_wavefront_card_t), &card); |
348 | if (card == NULL) | 349 | if (err < 0) |
349 | return NULL; | 350 | return err; |
350 | 351 | ||
351 | acard = card->private_data; | 352 | acard = card->private_data; |
352 | acard->wavefront.irq = -1; | 353 | acard->wavefront.irq = -1; |
@@ -357,7 +358,8 @@ static struct snd_card *snd_wavefront_card_new(int dev) | |||
357 | acard->wavefront.card = card; | 358 | acard->wavefront.card = card; |
358 | card->private_free = snd_wavefront_free; | 359 | card->private_free = snd_wavefront_free; |
359 | 360 | ||
360 | return card; | 361 | *cardp = card; |
362 | return 0; | ||
361 | } | 363 | } |
362 | 364 | ||
363 | static int __devinit | 365 | static int __devinit |
@@ -567,9 +569,9 @@ static int __devinit snd_wavefront_isa_probe(struct device *pdev, | |||
567 | struct snd_card *card; | 569 | struct snd_card *card; |
568 | int err; | 570 | int err; |
569 | 571 | ||
570 | card = snd_wavefront_card_new(dev); | 572 | err = snd_wavefront_card_new(dev, &card); |
571 | if (! card) | 573 | if (err < 0) |
572 | return -ENOMEM; | 574 | return err; |
573 | snd_card_set_dev(card, pdev); | 575 | snd_card_set_dev(card, pdev); |
574 | if ((err = snd_wavefront_probe(card, dev)) < 0) { | 576 | if ((err = snd_wavefront_probe(card, dev)) < 0) { |
575 | snd_card_free(card); | 577 | snd_card_free(card); |
@@ -616,9 +618,9 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, | |||
616 | if (dev >= SNDRV_CARDS) | 618 | if (dev >= SNDRV_CARDS) |
617 | return -ENODEV; | 619 | return -ENODEV; |
618 | 620 | ||
619 | card = snd_wavefront_card_new(dev); | 621 | res = snd_wavefront_card_new(dev, &card); |
620 | if (! card) | 622 | if (res < 0) |
621 | return -ENOMEM; | 623 | return res; |
622 | 624 | ||
623 | if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) { | 625 | if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) { |
624 | if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { | 626 | if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { |
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index 1881cec11e78..99e1391b2eb4 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c | |||
@@ -636,9 +636,10 @@ au1000_init(void) | |||
636 | struct snd_card *card; | 636 | struct snd_card *card; |
637 | struct snd_au1000 *au1000; | 637 | struct snd_au1000 *au1000; |
638 | 638 | ||
639 | card = snd_card_new(-1, "AC97", THIS_MODULE, sizeof(struct snd_au1000)); | 639 | err = snd_card_create(-1, "AC97", THIS_MODULE, |
640 | if (card == NULL) | 640 | sizeof(struct snd_au1000), &card); |
641 | return -ENOMEM; | 641 | if (err < 0) |
642 | return err; | ||
642 | 643 | ||
643 | card->private_free = snd_au1000_free; | 644 | card->private_free = snd_au1000_free; |
644 | au1000 = card->private_data; | 645 | au1000 = card->private_data; |
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index db495be01861..c52691c2fc46 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c | |||
@@ -878,9 +878,9 @@ static int __devinit hal2_probe(struct platform_device *pdev) | |||
878 | struct snd_hal2 *chip; | 878 | struct snd_hal2 *chip; |
879 | int err; | 879 | int err; |
880 | 880 | ||
881 | card = snd_card_new(index, id, THIS_MODULE, 0); | 881 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
882 | if (card == NULL) | 882 | if (err < 0) |
883 | return -ENOMEM; | 883 | return err; |
884 | 884 | ||
885 | err = hal2_create(card, &chip); | 885 | err = hal2_create(card, &chip); |
886 | if (err < 0) { | 886 | if (err < 0) { |
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 4c63504348dc..66f3b48ceafc 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c | |||
@@ -936,9 +936,9 @@ static int __devinit snd_sgio2audio_probe(struct platform_device *pdev) | |||
936 | struct snd_sgio2audio *chip; | 936 | struct snd_sgio2audio *chip; |
937 | int err; | 937 | int err; |
938 | 938 | ||
939 | card = snd_card_new(index, id, THIS_MODULE, 0); | 939 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
940 | if (card == NULL) | 940 | if (err < 0) |
941 | return -ENOMEM; | 941 | return err; |
942 | 942 | ||
943 | err = snd_sgio2audio_create(card, &chip); | 943 | err = snd_sgio2audio_create(card, &chip); |
944 | if (err < 0) { | 944 | if (err < 0) { |
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 41f870f8a11d..6055fd6d3b38 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c | |||
@@ -975,9 +975,9 @@ snd_harmony_probe(struct parisc_device *padev) | |||
975 | struct snd_card *card; | 975 | struct snd_card *card; |
976 | struct snd_harmony *h; | 976 | struct snd_harmony *h; |
977 | 977 | ||
978 | card = snd_card_new(index, id, THIS_MODULE, 0); | 978 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
979 | if (card == NULL) | 979 | if (err < 0) |
980 | return -ENOMEM; | 980 | return err; |
981 | 981 | ||
982 | err = snd_harmony_create(card, padev, &h); | 982 | err = snd_harmony_create(card, padev, &h); |
983 | if (err < 0) | 983 | if (err < 0) |
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index a7f38e63303f..d1f242bd0ac5 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c | |||
@@ -995,10 +995,10 @@ snd_ad1889_probe(struct pci_dev *pci, | |||
995 | } | 995 | } |
996 | 996 | ||
997 | /* (2) */ | 997 | /* (2) */ |
998 | card = snd_card_new(index[devno], id[devno], THIS_MODULE, 0); | 998 | err = snd_card_create(index[devno], id[devno], THIS_MODULE, 0, &card); |
999 | /* XXX REVISIT: we can probably allocate chip in this call */ | 999 | /* XXX REVISIT: we can probably allocate chip in this call */ |
1000 | if (card == NULL) | 1000 | if (err < 0) |
1001 | return -ENOMEM; | 1001 | return err; |
1002 | 1002 | ||
1003 | strcpy(card->driver, "AD1889"); | 1003 | strcpy(card->driver, "AD1889"); |
1004 | strcpy(card->shortname, "Analog Devices AD1889"); | 1004 | strcpy(card->shortname, "Analog Devices AD1889"); |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 1a0fd65ec280..b36c551da566 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -2307,9 +2307,9 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, | |||
2307 | 2307 | ||
2308 | snd_ali_printk("probe ...\n"); | 2308 | snd_ali_printk("probe ...\n"); |
2309 | 2309 | ||
2310 | card = snd_card_new(index, id, THIS_MODULE, 0); | 2310 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
2311 | if (!card) | 2311 | if (err < 0) |
2312 | return -ENOMEM; | 2312 | return err; |
2313 | 2313 | ||
2314 | err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); | 2314 | err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); |
2315 | if (err < 0) | 2315 | if (err < 0) |
diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 8df6824b51cd..f557c155db48 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c | |||
@@ -812,10 +812,10 @@ static int __devinit snd_als300_probe(struct pci_dev *pci, | |||
812 | return -ENOENT; | 812 | return -ENOENT; |
813 | } | 813 | } |
814 | 814 | ||
815 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 815 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
816 | 816 | ||
817 | if (card == NULL) | 817 | if (err < 0) |
818 | return -ENOMEM; | 818 | return err; |
819 | 819 | ||
820 | chip_type = pci_id->driver_data; | 820 | chip_type = pci_id->driver_data; |
821 | 821 | ||
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index ba570053d4d5..542a0c65a92c 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c | |||
@@ -889,12 +889,13 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
889 | pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO); | 889 | pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO); |
890 | pci_set_master(pci); | 890 | pci_set_master(pci); |
891 | 891 | ||
892 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 892 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
893 | sizeof(*acard) /* private_data: acard */); | 893 | sizeof(*acard) /* private_data: acard */, |
894 | if (card == NULL) { | 894 | &card); |
895 | if (err < 0) { | ||
895 | pci_release_regions(pci); | 896 | pci_release_regions(pci); |
896 | pci_disable_device(pci); | 897 | pci_disable_device(pci); |
897 | return -ENOMEM; | 898 | return err; |
898 | } | 899 | } |
899 | 900 | ||
900 | acard = card->private_data; | 901 | acard = card->private_data; |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 226fe8237d31..9ce8548c03e4 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -1645,9 +1645,9 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci, | |||
1645 | struct atiixp *chip; | 1645 | struct atiixp *chip; |
1646 | int err; | 1646 | int err; |
1647 | 1647 | ||
1648 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1648 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
1649 | if (card == NULL) | 1649 | if (err < 0) |
1650 | return -ENOMEM; | 1650 | return err; |
1651 | 1651 | ||
1652 | strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA"); | 1652 | strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA"); |
1653 | strcpy(card->shortname, "ATI IXP"); | 1653 | strcpy(card->shortname, "ATI IXP"); |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 0e6e5cc1c501..c3136cccc559 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -1288,9 +1288,9 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci, | |||
1288 | struct atiixp_modem *chip; | 1288 | struct atiixp_modem *chip; |
1289 | int err; | 1289 | int err; |
1290 | 1290 | ||
1291 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1291 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
1292 | if (card == NULL) | 1292 | if (err < 0) |
1293 | return -ENOMEM; | 1293 | return err; |
1294 | 1294 | ||
1295 | strcpy(card->driver, "ATIIXP-MODEM"); | 1295 | strcpy(card->driver, "ATIIXP-MODEM"); |
1296 | strcpy(card->shortname, "ATI IXP Modem"); | 1296 | strcpy(card->shortname, "ATI IXP Modem"); |
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index a36d4d1fd419..9ec122383eef 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c | |||
@@ -250,9 +250,9 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
250 | return -ENOENT; | 250 | return -ENOENT; |
251 | } | 251 | } |
252 | // (2) | 252 | // (2) |
253 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 253 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
254 | if (card == NULL) | 254 | if (err < 0) |
255 | return -ENOMEM; | 255 | return err; |
256 | 256 | ||
257 | // (3) | 257 | // (3) |
258 | if ((err = snd_vortex_create(card, pci, &chip)) < 0) { | 258 | if ((err = snd_vortex_create(card, pci, &chip)) < 0) { |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 3f00ddf450f8..eefcbf648ee1 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
@@ -368,9 +368,9 @@ static int __devinit snd_aw2_probe(struct pci_dev *pci, | |||
368 | } | 368 | } |
369 | 369 | ||
370 | /* (2) Create card instance */ | 370 | /* (2) Create card instance */ |
371 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 371 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
372 | if (card == NULL) | 372 | if (err < 0) |
373 | return -ENOMEM; | 373 | return err; |
374 | 374 | ||
375 | /* (3) Create main component */ | 375 | /* (3) Create main component */ |
376 | err = snd_aw2_create(card, pci, &chip); | 376 | err = snd_aw2_create(card, pci, &chip); |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 333007c523a1..1df96e76c483 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -2216,9 +2216,9 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
2216 | return -ENOENT; | 2216 | return -ENOENT; |
2217 | } | 2217 | } |
2218 | 2218 | ||
2219 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2219 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2220 | if (card == NULL) | 2220 | if (err < 0) |
2221 | return -ENOMEM; | 2221 | return err; |
2222 | 2222 | ||
2223 | strcpy(card->driver, "AZF3328"); | 2223 | strcpy(card->driver, "AZF3328"); |
2224 | strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); | 2224 | strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 1aa1c0402540..a299340519df 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -888,9 +888,9 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci, | |||
888 | return -ENOENT; | 888 | return -ENOENT; |
889 | } | 889 | } |
890 | 890 | ||
891 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 891 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
892 | if (!card) | 892 | if (err < 0) |
893 | return -ENOMEM; | 893 | return err; |
894 | 894 | ||
895 | err = snd_bt87x_create(card, pci, &chip); | 895 | err = snd_bt87x_create(card, pci, &chip); |
896 | if (err < 0) | 896 | if (err < 0) |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 0e62205d4081..b116456e7707 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -1707,9 +1707,9 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci, | |||
1707 | return -ENOENT; | 1707 | return -ENOENT; |
1708 | } | 1708 | } |
1709 | 1709 | ||
1710 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1710 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
1711 | if (card == NULL) | 1711 | if (err < 0) |
1712 | return -ENOMEM; | 1712 | return err; |
1713 | 1713 | ||
1714 | err = snd_ca0106_create(dev, card, pci, &chip); | 1714 | err = snd_ca0106_create(dev, card, pci, &chip); |
1715 | if (err < 0) | 1715 | if (err < 0) |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 1a74ca62c314..c7899c32aba1 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -3272,9 +3272,9 @@ static int __devinit snd_cmipci_probe(struct pci_dev *pci, | |||
3272 | return -ENOENT; | 3272 | return -ENOENT; |
3273 | } | 3273 | } |
3274 | 3274 | ||
3275 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 3275 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
3276 | if (card == NULL) | 3276 | if (err < 0) |
3277 | return -ENOMEM; | 3277 | return err; |
3278 | 3278 | ||
3279 | switch (pci->device) { | 3279 | switch (pci->device) { |
3280 | case PCI_DEVICE_ID_CMEDIA_CM8738: | 3280 | case PCI_DEVICE_ID_CMEDIA_CM8738: |
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 192e7842e181..b9b07f464631 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c | |||
@@ -1925,9 +1925,9 @@ static int __devinit snd_cs4281_probe(struct pci_dev *pci, | |||
1925 | return -ENOENT; | 1925 | return -ENOENT; |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1928 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
1929 | if (card == NULL) | 1929 | if (err < 0) |
1930 | return -ENOMEM; | 1930 | return err; |
1931 | 1931 | ||
1932 | if ((err = snd_cs4281_create(card, pci, &chip, dual_codec[dev])) < 0) { | 1932 | if ((err = snd_cs4281_create(card, pci, &chip, dual_codec[dev])) < 0) { |
1933 | snd_card_free(card); | 1933 | snd_card_free(card); |
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index e876b3263e46..c9b3e3d48cbc 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c | |||
@@ -88,9 +88,9 @@ static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, | |||
88 | return -ENOENT; | 88 | return -ENOENT; |
89 | } | 89 | } |
90 | 90 | ||
91 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 91 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
92 | if (card == NULL) | 92 | if (err < 0) |
93 | return -ENOMEM; | 93 | return err; |
94 | if ((err = snd_cs46xx_create(card, pci, | 94 | if ((err = snd_cs46xx_create(card, pci, |
95 | external_amp[dev], thinkpad[dev], | 95 | external_amp[dev], thinkpad[dev], |
96 | &chip)) < 0) { | 96 | &chip)) < 0) { |
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c index 6dea5b5cc774..dc464321d0f3 100644 --- a/sound/pci/cs5530.c +++ b/sound/pci/cs5530.c | |||
@@ -258,10 +258,10 @@ static int __devinit snd_cs5530_probe(struct pci_dev *pci, | |||
258 | return -ENOENT; | 258 | return -ENOENT; |
259 | } | 259 | } |
260 | 260 | ||
261 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 261 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
262 | 262 | ||
263 | if (card == NULL) | 263 | if (err < 0) |
264 | return -ENOMEM; | 264 | return err; |
265 | 265 | ||
266 | err = snd_cs5530_create(card, pci, &chip); | 266 | err = snd_cs5530_create(card, pci, &chip); |
267 | if (err < 0) { | 267 | if (err < 0) { |
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index 826e6dec2e97..ac1d72e0a1e4 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c | |||
@@ -353,9 +353,9 @@ static int __devinit snd_cs5535audio_probe(struct pci_dev *pci, | |||
353 | return -ENOENT; | 353 | return -ENOENT; |
354 | } | 354 | } |
355 | 355 | ||
356 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 356 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
357 | if (card == NULL) | 357 | if (err < 0) |
358 | return -ENOMEM; | 358 | return err; |
359 | 359 | ||
360 | if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0) | 360 | if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0) |
361 | goto probefail_out; | 361 | goto probefail_out; |
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 8dbc5c4ba421..9d015a76eb69 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -1997,9 +1997,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, | |||
1997 | 1997 | ||
1998 | DE_INIT(("Echoaudio driver starting...\n")); | 1998 | DE_INIT(("Echoaudio driver starting...\n")); |
1999 | i = 0; | 1999 | i = 0; |
2000 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2000 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2001 | if (card == NULL) | 2001 | if (err < 0) |
2002 | return -ENOMEM; | 2002 | return err; |
2003 | 2003 | ||
2004 | snd_card_set_dev(card, &pci->dev); | 2004 | snd_card_set_dev(card, &pci->dev); |
2005 | 2005 | ||
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 8354c1a83312..c7f3b994101c 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -114,9 +114,9 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, | |||
114 | return -ENOENT; | 114 | return -ENOENT; |
115 | } | 115 | } |
116 | 116 | ||
117 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 117 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
118 | if (card == NULL) | 118 | if (err < 0) |
119 | return -ENOMEM; | 119 | return err; |
120 | if (max_buffer_size[dev] < 32) | 120 | if (max_buffer_size[dev] < 32) |
121 | max_buffer_size[dev] = 32; | 121 | max_buffer_size[dev] = 32; |
122 | else if (max_buffer_size[dev] > 1024) | 122 | else if (max_buffer_size[dev] > 1024) |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 5ff4dbb62dad..31542adc6b7e 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -1544,9 +1544,9 @@ static int __devinit snd_emu10k1x_probe(struct pci_dev *pci, | |||
1544 | return -ENOENT; | 1544 | return -ENOENT; |
1545 | } | 1545 | } |
1546 | 1546 | ||
1547 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1547 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
1548 | if (card == NULL) | 1548 | if (err < 0) |
1549 | return -ENOMEM; | 1549 | return err; |
1550 | 1550 | ||
1551 | if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) { | 1551 | if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) { |
1552 | snd_card_free(card); | 1552 | snd_card_free(card); |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 9bf95367c882..e00614cbceff 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -2409,9 +2409,9 @@ static int __devinit snd_audiopci_probe(struct pci_dev *pci, | |||
2409 | return -ENOENT; | 2409 | return -ENOENT; |
2410 | } | 2410 | } |
2411 | 2411 | ||
2412 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2412 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2413 | if (card == NULL) | 2413 | if (err < 0) |
2414 | return -ENOMEM; | 2414 | return err; |
2415 | 2415 | ||
2416 | if ((err = snd_ensoniq_create(card, pci, &ensoniq)) < 0) { | 2416 | if ((err = snd_ensoniq_create(card, pci, &ensoniq)) < 0) { |
2417 | snd_card_free(card); | 2417 | snd_card_free(card); |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 4cd9a1faaecc..34a78afc26d0 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -1799,9 +1799,9 @@ static int __devinit snd_es1938_probe(struct pci_dev *pci, | |||
1799 | return -ENOENT; | 1799 | return -ENOENT; |
1800 | } | 1800 | } |
1801 | 1801 | ||
1802 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1802 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
1803 | if (card == NULL) | 1803 | if (err < 0) |
1804 | return -ENOMEM; | 1804 | return err; |
1805 | for (idx = 0; idx < 5; idx++) { | 1805 | for (idx = 0; idx < 5; idx++) { |
1806 | if (pci_resource_start(pci, idx) == 0 || | 1806 | if (pci_resource_start(pci, idx) == 0 || |
1807 | !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) { | 1807 | !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) { |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index e9c3794bbcb8..dc97e8116141 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -2645,9 +2645,9 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, | |||
2645 | return -ENOENT; | 2645 | return -ENOENT; |
2646 | } | 2646 | } |
2647 | 2647 | ||
2648 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2648 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2649 | if (!card) | 2649 | if (err < 0) |
2650 | return -ENOMEM; | 2650 | return err; |
2651 | 2651 | ||
2652 | if (total_bufsize[dev] < 128) | 2652 | if (total_bufsize[dev] < 128) |
2653 | total_bufsize[dev] = 128; | 2653 | total_bufsize[dev] = 128; |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index c129f9e2072c..60cdb9e0b68d 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -1468,9 +1468,9 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci, | |||
1468 | return -ENOENT; | 1468 | return -ENOENT; |
1469 | } | 1469 | } |
1470 | 1470 | ||
1471 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1471 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
1472 | if (card == NULL) | 1472 | if (err < 0) |
1473 | return -ENOMEM; | 1473 | return err; |
1474 | if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) { | 1474 | if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) { |
1475 | snd_card_free(card); | 1475 | snd_card_free(card); |
1476 | return err; | 1476 | return err; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 11e791b965f6..f9603443f086 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2335,10 +2335,10 @@ static int __devinit azx_probe(struct pci_dev *pci, | |||
2335 | return -ENOENT; | 2335 | return -ENOENT; |
2336 | } | 2336 | } |
2337 | 2337 | ||
2338 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2338 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2339 | if (!card) { | 2339 | if (err < 0) { |
2340 | snd_printk(KERN_ERR SFX "Error creating card!\n"); | 2340 | snd_printk(KERN_ERR SFX "Error creating card!\n"); |
2341 | return -ENOMEM; | 2341 | return err; |
2342 | } | 2342 | } |
2343 | 2343 | ||
2344 | err = azx_create(card, pci, dev, pci_id->driver_data, &chip); | 2344 | err = azx_create(card, pci, dev, pci_id->driver_data, &chip); |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 58d7cda03de5..bab1c700f497 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -2648,9 +2648,9 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, | |||
2648 | return -ENOENT; | 2648 | return -ENOENT; |
2649 | } | 2649 | } |
2650 | 2650 | ||
2651 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2651 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2652 | if (card == NULL) | 2652 | if (err < 0) |
2653 | return -ENOMEM; | 2653 | return err; |
2654 | 2654 | ||
2655 | strcpy(card->driver, "ICE1712"); | 2655 | strcpy(card->driver, "ICE1712"); |
2656 | strcpy(card->shortname, "ICEnsemble ICE1712"); | 2656 | strcpy(card->shortname, "ICEnsemble ICE1712"); |
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index bb8d8c766b9d..7ff36d3f0f44 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -2456,9 +2456,9 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, | |||
2456 | return -ENOENT; | 2456 | return -ENOENT; |
2457 | } | 2457 | } |
2458 | 2458 | ||
2459 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2459 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2460 | if (card == NULL) | 2460 | if (err < 0) |
2461 | return -ENOMEM; | 2461 | return err; |
2462 | 2462 | ||
2463 | strcpy(card->driver, "ICE1724"); | 2463 | strcpy(card->driver, "ICE1724"); |
2464 | strcpy(card->shortname, "ICEnsemble ICE1724"); | 2464 | strcpy(card->shortname, "ICEnsemble ICE1724"); |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 19d3391e229f..671ff65db029 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -3058,9 +3058,9 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | |||
3058 | int err; | 3058 | int err; |
3059 | struct shortname_table *name; | 3059 | struct shortname_table *name; |
3060 | 3060 | ||
3061 | card = snd_card_new(index, id, THIS_MODULE, 0); | 3061 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
3062 | if (card == NULL) | 3062 | if (err < 0) |
3063 | return -ENOMEM; | 3063 | return err; |
3064 | 3064 | ||
3065 | if (spdif_aclink < 0) | 3065 | if (spdif_aclink < 0) |
3066 | spdif_aclink = check_default_spdif_aclink(pci); | 3066 | spdif_aclink = check_default_spdif_aclink(pci); |
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 93449e464566..33a843c19316 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c | |||
@@ -1269,9 +1269,9 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci, | |||
1269 | int err; | 1269 | int err; |
1270 | struct shortname_table *name; | 1270 | struct shortname_table *name; |
1271 | 1271 | ||
1272 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1272 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
1273 | if (card == NULL) | 1273 | if (err < 0) |
1274 | return -ENOMEM; | 1274 | return err; |
1275 | 1275 | ||
1276 | strcpy(card->driver, "ICH-MODEM"); | 1276 | strcpy(card->driver, "ICH-MODEM"); |
1277 | strcpy(card->shortname, "Intel ICH"); | 1277 | strcpy(card->shortname, "Intel ICH"); |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 5f8006b42750..8b79969034be 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -2443,9 +2443,9 @@ snd_korg1212_probe(struct pci_dev *pci, | |||
2443 | dev++; | 2443 | dev++; |
2444 | return -ENOENT; | 2444 | return -ENOENT; |
2445 | } | 2445 | } |
2446 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2446 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2447 | if (card == NULL) | 2447 | if (err < 0) |
2448 | return -ENOMEM; | 2448 | return err; |
2449 | 2449 | ||
2450 | if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) { | 2450 | if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) { |
2451 | snd_card_free(card); | 2451 | snd_card_free(card); |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 59bbaf8f3e5b..70141548f251 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -2691,9 +2691,9 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
2691 | return -ENOENT; | 2691 | return -ENOENT; |
2692 | } | 2692 | } |
2693 | 2693 | ||
2694 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2694 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2695 | if (card == NULL) | 2695 | if (err < 0) |
2696 | return -ENOMEM; | 2696 | return err; |
2697 | 2697 | ||
2698 | switch (pci->device) { | 2698 | switch (pci->device) { |
2699 | case PCI_DEVICE_ID_ESS_ALLEGRO: | 2699 | case PCI_DEVICE_ID_ESS_ALLEGRO: |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index f23a73577c22..bfc19e36c4b6 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -1365,12 +1365,12 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, | |||
1365 | else | 1365 | else |
1366 | idx = index[dev] + i; | 1366 | idx = index[dev] + i; |
1367 | snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i); | 1367 | snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i); |
1368 | card = snd_card_new(idx, tmpid, THIS_MODULE, 0); | 1368 | err = snd_card_create(idx, tmpid, THIS_MODULE, 0, &card); |
1369 | 1369 | ||
1370 | if (! card) { | 1370 | if (err < 0) { |
1371 | snd_printk(KERN_ERR "cannot allocate the card %d\n", i); | 1371 | snd_printk(KERN_ERR "cannot allocate the card %d\n", i); |
1372 | snd_mixart_free(mgr); | 1372 | snd_mixart_free(mgr); |
1373 | return -ENOMEM; | 1373 | return err; |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | strcpy(card->driver, CARD_NAME); | 1376 | strcpy(card->driver, CARD_NAME); |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 50c9f8a05082..522a040855d4 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -1668,9 +1668,9 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, | |||
1668 | } | 1668 | } |
1669 | } | 1669 | } |
1670 | 1670 | ||
1671 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1671 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
1672 | if (card == NULL) | 1672 | if (err < 0) |
1673 | return -ENOMEM; | 1673 | return err; |
1674 | 1674 | ||
1675 | switch (pci->device) { | 1675 | switch (pci->device) { |
1676 | case PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO: | 1676 | case PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO: |
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 84f481d41efa..9c81e0b05113 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
@@ -459,10 +459,10 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, | |||
459 | struct oxygen *chip; | 459 | struct oxygen *chip; |
460 | int err; | 460 | int err; |
461 | 461 | ||
462 | card = snd_card_new(index, id, model->owner, | 462 | err = snd_card_create(index, id, model->owner, |
463 | sizeof *chip + model->model_data_size); | 463 | sizeof(*chip) + model->model_data_size, &card); |
464 | if (!card) | 464 | if (err < 0) |
465 | return -ENOMEM; | 465 | return err; |
466 | 466 | ||
467 | chip = card->private_data; | 467 | chip = card->private_data; |
468 | chip->card = card; | 468 | chip->card = card; |
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 27cf2c28d113..7f95459c8b1f 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c | |||
@@ -1510,12 +1510,12 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, | |||
1510 | 1510 | ||
1511 | snprintf(tmpid, sizeof(tmpid), "%s-%d", | 1511 | snprintf(tmpid, sizeof(tmpid), "%s-%d", |
1512 | id[dev] ? id[dev] : card_name, i); | 1512 | id[dev] ? id[dev] : card_name, i); |
1513 | card = snd_card_new(idx, tmpid, THIS_MODULE, 0); | 1513 | err = snd_card_create(idx, tmpid, THIS_MODULE, 0, &card); |
1514 | 1514 | ||
1515 | if (! card) { | 1515 | if (err < 0) { |
1516 | snd_printk(KERN_ERR "cannot allocate the card %d\n", i); | 1516 | snd_printk(KERN_ERR "cannot allocate the card %d\n", i); |
1517 | pcxhr_free(mgr); | 1517 | pcxhr_free(mgr); |
1518 | return -ENOMEM; | 1518 | return err; |
1519 | } | 1519 | } |
1520 | 1520 | ||
1521 | strcpy(card->driver, DRIVER_NAME); | 1521 | strcpy(card->driver, DRIVER_NAME); |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 3caacfb9d8e0..6f1034417a02 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
@@ -2102,9 +2102,9 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
2102 | return -ENOENT; | 2102 | return -ENOENT; |
2103 | } | 2103 | } |
2104 | 2104 | ||
2105 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 2105 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
2106 | if (card == NULL) | 2106 | if (err < 0) |
2107 | return -ENOMEM; | 2107 | return err; |
2108 | if ((err = snd_riptide_create(card, pci, &chip)) < 0) { | 2108 | if ((err = snd_riptide_create(card, pci, &chip)) < 0) { |
2109 | snd_card_free(card); | 2109 | snd_card_free(card); |
2110 | return err; | 2110 | return err; |
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index e7ef3a1a25a8..d7b966e7c4cf 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
@@ -1941,9 +1941,10 @@ snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
1941 | return -ENOENT; | 1941 | return -ENOENT; |
1942 | } | 1942 | } |
1943 | 1943 | ||
1944 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 1944 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
1945 | sizeof(struct rme32))) == NULL) | 1945 | sizeof(struct rme32), &card); |
1946 | return -ENOMEM; | 1946 | if (err < 0) |
1947 | return err; | ||
1947 | card->private_free = snd_rme32_card_free; | 1948 | card->private_free = snd_rme32_card_free; |
1948 | rme32 = (struct rme32 *) card->private_data; | 1949 | rme32 = (struct rme32 *) card->private_data; |
1949 | rme32->card = card; | 1950 | rme32->card = card; |
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 3fdd488d0975..55fb1c131f58 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
@@ -2348,9 +2348,10 @@ snd_rme96_probe(struct pci_dev *pci, | |||
2348 | dev++; | 2348 | dev++; |
2349 | return -ENOENT; | 2349 | return -ENOENT; |
2350 | } | 2350 | } |
2351 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 2351 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
2352 | sizeof(struct rme96))) == NULL) | 2352 | sizeof(struct rme96), &card); |
2353 | return -ENOMEM; | 2353 | if (err < 0) |
2354 | return err; | ||
2354 | card->private_free = snd_rme96_card_free; | 2355 | card->private_free = snd_rme96_card_free; |
2355 | rme96 = (struct rme96 *)card->private_data; | 2356 | rme96 = (struct rme96 *)card->private_data; |
2356 | rme96->card = card; | 2357 | rme96->card = card; |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 44d0c15e2b71..05b3f795a168 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -5158,8 +5158,10 @@ static int __devinit snd_hdsp_probe(struct pci_dev *pci, | |||
5158 | return -ENOENT; | 5158 | return -ENOENT; |
5159 | } | 5159 | } |
5160 | 5160 | ||
5161 | if (!(card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct hdsp)))) | 5161 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
5162 | return -ENOMEM; | 5162 | sizeof(struct hdsp), &card); |
5163 | if (err < 0) | ||
5164 | return err; | ||
5163 | 5165 | ||
5164 | hdsp = (struct hdsp *) card->private_data; | 5166 | hdsp = (struct hdsp *) card->private_data; |
5165 | card->private_free = snd_hdsp_card_free; | 5167 | card->private_free = snd_hdsp_card_free; |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 71231cf1b2b0..d4b4e0d0fee8 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -4503,10 +4503,10 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci, | |||
4503 | return -ENOENT; | 4503 | return -ENOENT; |
4504 | } | 4504 | } |
4505 | 4505 | ||
4506 | card = snd_card_new(index[dev], id[dev], | 4506 | err = snd_card_create(index[dev], id[dev], |
4507 | THIS_MODULE, sizeof(struct hdspm)); | 4507 | THIS_MODULE, sizeof(struct hdspm), &card); |
4508 | if (!card) | 4508 | if (err < 0) |
4509 | return -ENOMEM; | 4509 | return err; |
4510 | 4510 | ||
4511 | hdspm = card->private_data; | 4511 | hdspm = card->private_data; |
4512 | card->private_free = snd_hdspm_card_free; | 4512 | card->private_free = snd_hdspm_card_free; |
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 2570907134d7..bc539abb2105 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -2594,11 +2594,11 @@ static int __devinit snd_rme9652_probe(struct pci_dev *pci, | |||
2594 | return -ENOENT; | 2594 | return -ENOENT; |
2595 | } | 2595 | } |
2596 | 2596 | ||
2597 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 2597 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
2598 | sizeof(struct snd_rme9652)); | 2598 | sizeof(struct snd_rme9652), &card); |
2599 | 2599 | ||
2600 | if (!card) | 2600 | if (err < 0) |
2601 | return -ENOMEM; | 2601 | return err; |
2602 | 2602 | ||
2603 | rme9652 = (struct snd_rme9652 *) card->private_data; | 2603 | rme9652 = (struct snd_rme9652 *) card->private_data; |
2604 | card->private_free = snd_rme9652_card_free; | 2604 | card->private_free = snd_rme9652_card_free; |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index df2007e3be7c..baf6d8e3dabc 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
@@ -1387,9 +1387,8 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, | |||
1387 | if (!enable) | 1387 | if (!enable) |
1388 | goto error_out; | 1388 | goto error_out; |
1389 | 1389 | ||
1390 | rc = -ENOMEM; | 1390 | rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); |
1391 | card = snd_card_new(index, id, THIS_MODULE, sizeof(*sis)); | 1391 | if (rc < 0) |
1392 | if (!card) | ||
1393 | goto error_out; | 1392 | goto error_out; |
1394 | 1393 | ||
1395 | strcpy(card->driver, "SiS7019"); | 1394 | strcpy(card->driver, "SiS7019"); |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index cd408b86c839..c5601b0ad7cc 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -1423,9 +1423,9 @@ static int __devinit snd_sonic_probe(struct pci_dev *pci, | |||
1423 | return -ENOENT; | 1423 | return -ENOENT; |
1424 | } | 1424 | } |
1425 | 1425 | ||
1426 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1426 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
1427 | if (card == NULL) | 1427 | if (err < 0) |
1428 | return -ENOMEM; | 1428 | return err; |
1429 | for (idx = 0; idx < 5; idx++) { | 1429 | for (idx = 0; idx < 5; idx++) { |
1430 | if (pci_resource_start(pci, idx) == 0 || | 1430 | if (pci_resource_start(pci, idx) == 0 || |
1431 | !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) { | 1431 | !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) { |
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index d94b16ffb385..21cef97d478d 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c | |||
@@ -89,9 +89,9 @@ static int __devinit snd_trident_probe(struct pci_dev *pci, | |||
89 | return -ENOENT; | 89 | return -ENOENT; |
90 | } | 90 | } |
91 | 91 | ||
92 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 92 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
93 | if (card == NULL) | 93 | if (err < 0) |
94 | return -ENOMEM; | 94 | return err; |
95 | 95 | ||
96 | if ((err = snd_trident_create(card, pci, | 96 | if ((err = snd_trident_create(card, pci, |
97 | pcm_channels[dev], | 97 | pcm_channels[dev], |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 1aafe956ee2b..d8705547dae1 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -2433,9 +2433,9 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci, | |||
2433 | unsigned int i; | 2433 | unsigned int i; |
2434 | int err; | 2434 | int err; |
2435 | 2435 | ||
2436 | card = snd_card_new(index, id, THIS_MODULE, 0); | 2436 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
2437 | if (card == NULL) | 2437 | if (err < 0) |
2438 | return -ENOMEM; | 2438 | return err; |
2439 | 2439 | ||
2440 | card_type = pci_id->driver_data; | 2440 | card_type = pci_id->driver_data; |
2441 | switch (card_type) { | 2441 | switch (card_type) { |
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 5bd79d2a5a15..c086b762c150 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
@@ -1167,9 +1167,9 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci, | |||
1167 | unsigned int i; | 1167 | unsigned int i; |
1168 | int err; | 1168 | int err; |
1169 | 1169 | ||
1170 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1170 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
1171 | if (card == NULL) | 1171 | if (err < 0) |
1172 | return -ENOMEM; | 1172 | return err; |
1173 | 1173 | ||
1174 | card_type = pci_id->driver_data; | 1174 | card_type = pci_id->driver_data; |
1175 | switch (card_type) { | 1175 | switch (card_type) { |
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c index acc352f4a441..fc9136c3e0d7 100644 --- a/sound/pci/vx222/vx222.c +++ b/sound/pci/vx222/vx222.c | |||
@@ -204,9 +204,9 @@ static int __devinit snd_vx222_probe(struct pci_dev *pci, | |||
204 | return -ENOENT; | 204 | return -ENOENT; |
205 | } | 205 | } |
206 | 206 | ||
207 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 207 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
208 | if (card == NULL) | 208 | if (err < 0) |
209 | return -ENOMEM; | 209 | return err; |
210 | 210 | ||
211 | switch ((int)pci_id->driver_data) { | 211 | switch ((int)pci_id->driver_data) { |
212 | case VX_PCI_VX222_OLD: | 212 | case VX_PCI_VX222_OLD: |
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 2631a554845e..4af66661f9b0 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c | |||
@@ -187,9 +187,9 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, | |||
187 | return -ENOENT; | 187 | return -ENOENT; |
188 | } | 188 | } |
189 | 189 | ||
190 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 190 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
191 | if (card == NULL) | 191 | if (err < 0) |
192 | return -ENOMEM; | 192 | return err; |
193 | 193 | ||
194 | switch (pci_id->device) { | 194 | switch (pci_id->device) { |
195 | case 0x0004: str = "YMF724"; model = "DS-1"; break; | 195 | case 0x0004: str = "YMF724"; model = "DS-1"; break; |
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 819aaaac432f..7dea74b71cf1 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c | |||
@@ -91,7 +91,7 @@ static int snd_pdacf_dev_free(struct snd_device *device) | |||
91 | */ | 91 | */ |
92 | static int snd_pdacf_probe(struct pcmcia_device *link) | 92 | static int snd_pdacf_probe(struct pcmcia_device *link) |
93 | { | 93 | { |
94 | int i; | 94 | int i, err; |
95 | struct snd_pdacf *pdacf; | 95 | struct snd_pdacf *pdacf; |
96 | struct snd_card *card; | 96 | struct snd_card *card; |
97 | static struct snd_device_ops ops = { | 97 | static struct snd_device_ops ops = { |
@@ -112,20 +112,23 @@ static int snd_pdacf_probe(struct pcmcia_device *link) | |||
112 | return -ENODEV; /* disabled explicitly */ | 112 | return -ENODEV; /* disabled explicitly */ |
113 | 113 | ||
114 | /* ok, create a card instance */ | 114 | /* ok, create a card instance */ |
115 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); | 115 | err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card); |
116 | if (card == NULL) { | 116 | if (err < 0) { |
117 | snd_printk(KERN_ERR "pdacf: cannot create a card instance\n"); | 117 | snd_printk(KERN_ERR "pdacf: cannot create a card instance\n"); |
118 | return -ENOMEM; | 118 | return err; |
119 | } | 119 | } |
120 | 120 | ||
121 | pdacf = snd_pdacf_create(card); | 121 | pdacf = snd_pdacf_create(card); |
122 | if (! pdacf) | 122 | if (!pdacf) { |
123 | return -EIO; | 123 | snd_card_free(card); |
124 | return -ENOMEM; | ||
125 | } | ||
124 | 126 | ||
125 | if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) { | 127 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops); |
128 | if (err < 0) { | ||
126 | kfree(pdacf); | 129 | kfree(pdacf); |
127 | snd_card_free(card); | 130 | snd_card_free(card); |
128 | return -ENODEV; | 131 | return err; |
129 | } | 132 | } |
130 | 133 | ||
131 | snd_card_set_dev(card, &handle_to_dev(link)); | 134 | snd_card_set_dev(card, &handle_to_dev(link)); |
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 706602a40600..7445cc8a47d3 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -130,23 +130,26 @@ static struct snd_vx_hardware vxp440_hw = { | |||
130 | /* | 130 | /* |
131 | * create vxpocket instance | 131 | * create vxpocket instance |
132 | */ | 132 | */ |
133 | static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl, | 133 | static int snd_vxpocket_new(struct snd_card *card, int ibl, |
134 | struct pcmcia_device *link) | 134 | struct pcmcia_device *link, |
135 | struct snd_vxpocket **chip_ret) | ||
135 | { | 136 | { |
136 | struct vx_core *chip; | 137 | struct vx_core *chip; |
137 | struct snd_vxpocket *vxp; | 138 | struct snd_vxpocket *vxp; |
138 | static struct snd_device_ops ops = { | 139 | static struct snd_device_ops ops = { |
139 | .dev_free = snd_vxpocket_dev_free, | 140 | .dev_free = snd_vxpocket_dev_free, |
140 | }; | 141 | }; |
142 | int err; | ||
141 | 143 | ||
142 | chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops, | 144 | chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops, |
143 | sizeof(struct snd_vxpocket) - sizeof(struct vx_core)); | 145 | sizeof(struct snd_vxpocket) - sizeof(struct vx_core)); |
144 | if (! chip) | 146 | if (!chip) |
145 | return NULL; | 147 | return -ENOMEM; |
146 | 148 | ||
147 | if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) { | 149 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); |
150 | if (err < 0) { | ||
148 | kfree(chip); | 151 | kfree(chip); |
149 | return NULL; | 152 | return err; |
150 | } | 153 | } |
151 | chip->ibl.size = ibl; | 154 | chip->ibl.size = ibl; |
152 | 155 | ||
@@ -169,7 +172,8 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl, | |||
169 | link->conf.ConfigIndex = 1; | 172 | link->conf.ConfigIndex = 1; |
170 | link->conf.Present = PRESENT_OPTION; | 173 | link->conf.Present = PRESENT_OPTION; |
171 | 174 | ||
172 | return vxp; | 175 | *chip_ret = vxp; |
176 | return 0; | ||
173 | } | 177 | } |
174 | 178 | ||
175 | 179 | ||
@@ -292,7 +296,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) | |||
292 | { | 296 | { |
293 | struct snd_card *card; | 297 | struct snd_card *card; |
294 | struct snd_vxpocket *vxp; | 298 | struct snd_vxpocket *vxp; |
295 | int i; | 299 | int i, err; |
296 | 300 | ||
297 | /* find an empty slot from the card list */ | 301 | /* find an empty slot from the card list */ |
298 | for (i = 0; i < SNDRV_CARDS; i++) { | 302 | for (i = 0; i < SNDRV_CARDS; i++) { |
@@ -307,16 +311,16 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) | |||
307 | return -ENODEV; /* disabled explicitly */ | 311 | return -ENODEV; /* disabled explicitly */ |
308 | 312 | ||
309 | /* ok, create a card instance */ | 313 | /* ok, create a card instance */ |
310 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); | 314 | err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card); |
311 | if (card == NULL) { | 315 | if (err < 0) { |
312 | snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); | 316 | snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); |
313 | return -ENOMEM; | 317 | return err; |
314 | } | 318 | } |
315 | 319 | ||
316 | vxp = snd_vxpocket_new(card, ibl[i], p_dev); | 320 | err = snd_vxpocket_new(card, ibl[i], p_dev, &vxp); |
317 | if (! vxp) { | 321 | if (err < 0) { |
318 | snd_card_free(card); | 322 | snd_card_free(card); |
319 | return -ENODEV; | 323 | return err; |
320 | } | 324 | } |
321 | card->private_data = vxp; | 325 | card->private_data = vxp; |
322 | 326 | ||
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c index c936225771ba..2e18ed0ea899 100644 --- a/sound/ppc/powermac.c +++ b/sound/ppc/powermac.c | |||
@@ -58,9 +58,9 @@ static int __init snd_pmac_probe(struct platform_device *devptr) | |||
58 | char *name_ext; | 58 | char *name_ext; |
59 | int err; | 59 | int err; |
60 | 60 | ||
61 | card = snd_card_new(index, id, THIS_MODULE, 0); | 61 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
62 | if (card == NULL) | 62 | if (err < 0) |
63 | return -ENOMEM; | 63 | return err; |
64 | 64 | ||
65 | if ((err = snd_pmac_new(card, &chip)) < 0) | 65 | if ((err = snd_pmac_new(card, &chip)) < 0) |
66 | goto __error; | 66 | goto __error; |
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 8f9e3859c37c..ef2c3f417175 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
@@ -969,11 +969,9 @@ static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) | |||
969 | } | 969 | } |
970 | 970 | ||
971 | /* create card instance */ | 971 | /* create card instance */ |
972 | the_card.card = snd_card_new(index, id, THIS_MODULE, 0); | 972 | ret = snd_card_create(index, id, THIS_MODULE, 0, &the_card.card); |
973 | if (!the_card.card) { | 973 | if (ret < 0) |
974 | ret = -ENXIO; | ||
975 | goto clean_irq; | 974 | goto clean_irq; |
976 | } | ||
977 | 975 | ||
978 | strcpy(the_card.card->driver, "PS3"); | 976 | strcpy(the_card.card->driver, "PS3"); |
979 | strcpy(the_card.card->shortname, "PS3"); | 977 | strcpy(the_card.card->shortname, "PS3"); |
diff --git a/sound/sh/aica.c b/sound/sh/aica.c index 7c920f3e7fe3..f551233c5a08 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c | |||
@@ -609,11 +609,11 @@ static int __devinit snd_aica_probe(struct platform_device *devptr) | |||
609 | dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL); | 609 | dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL); |
610 | if (unlikely(!dreamcastcard)) | 610 | if (unlikely(!dreamcastcard)) |
611 | return -ENOMEM; | 611 | return -ENOMEM; |
612 | dreamcastcard->card = | 612 | err = snd_card_create(index, SND_AICA_DRIVER, THIS_MODULE, 0, |
613 | snd_card_new(index, SND_AICA_DRIVER, THIS_MODULE, 0); | 613 | &dreamcastcard->card); |
614 | if (unlikely(!dreamcastcard->card)) { | 614 | if (unlikely(err < 0)) { |
615 | kfree(dreamcastcard); | 615 | kfree(dreamcastcard); |
616 | return -ENODEV; | 616 | return err; |
617 | } | 617 | } |
618 | strcpy(dreamcastcard->card->driver, "snd_aica"); | 618 | strcpy(dreamcastcard->card->driver, "snd_aica"); |
619 | strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER); | 619 | strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER); |
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index ef025c66cc66..3d2bb6fc6dcc 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -6,6 +6,7 @@ menuconfig SND_SOC | |||
6 | tristate "ALSA for SoC audio support" | 6 | tristate "ALSA for SoC audio support" |
7 | select SND_PCM | 7 | select SND_PCM |
8 | select AC97_BUS if SND_SOC_AC97_BUS | 8 | select AC97_BUS if SND_SOC_AC97_BUS |
9 | select SND_JACK if INPUT=y || INPUT=SND | ||
9 | ---help--- | 10 | ---help--- |
10 | 11 | ||
11 | If you want ASoC support, you should say Y here and also to the | 12 | If you want ASoC support, you should say Y here and also to the |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 86a9b1f5b0f3..0237879fd412 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | snd-soc-core-objs := soc-core.o soc-dapm.o | 1 | snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o |
2 | 2 | ||
3 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o | 3 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o |
4 | obj-$(CONFIG_SND_SOC) += codecs/ | 4 | obj-$(CONFIG_SND_SOC) += codecs/ |
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index 3dcdc4e3cfa0..9ef6b96373f5 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c | |||
@@ -347,7 +347,7 @@ static int atmel_pcm_mmap(struct snd_pcm_substream *substream, | |||
347 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 347 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
348 | } | 348 | } |
349 | 349 | ||
350 | struct snd_pcm_ops atmel_pcm_ops = { | 350 | static struct snd_pcm_ops atmel_pcm_ops = { |
351 | .open = atmel_pcm_open, | 351 | .open = atmel_pcm_open, |
352 | .close = atmel_pcm_close, | 352 | .close = atmel_pcm_close, |
353 | .ioctl = snd_pcm_lib_ioctl, | 353 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index bc8d654576c0..30490a259148 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c | |||
@@ -305,7 +305,7 @@ static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) | |||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
308 | struct snd_pcm_ops au1xpsc_pcm_ops = { | 308 | static struct snd_pcm_ops au1xpsc_pcm_ops = { |
309 | .open = au1xpsc_pcm_open, | 309 | .open = au1xpsc_pcm_open, |
310 | .close = au1xpsc_pcm_close, | 310 | .close = au1xpsc_pcm_close, |
311 | .ioctl = snd_pcm_lib_ioctl, | 311 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 8067cfafa3a7..8cfed1a5dcbe 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c | |||
@@ -297,7 +297,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | |||
297 | } | 297 | } |
298 | #endif | 298 | #endif |
299 | 299 | ||
300 | struct snd_pcm_ops bf5xx_pcm_ac97_ops = { | 300 | static struct snd_pcm_ops bf5xx_pcm_ac97_ops = { |
301 | .open = bf5xx_pcm_open, | 301 | .open = bf5xx_pcm_open, |
302 | .ioctl = snd_pcm_lib_ioctl, | 302 | .ioctl = snd_pcm_lib_ioctl, |
303 | .hw_params = bf5xx_pcm_hw_params, | 303 | .hw_params = bf5xx_pcm_hw_params, |
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index 3be2be60576d..5885702c78ff 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c | |||
@@ -31,72 +31,46 @@ | |||
31 | #include "bf5xx-sport.h" | 31 | #include "bf5xx-sport.h" |
32 | #include "bf5xx-ac97.h" | 32 | #include "bf5xx-ac97.h" |
33 | 33 | ||
34 | #if defined(CONFIG_BF54x) | ||
35 | #define PIN_REQ_SPORT_0 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, \ | ||
36 | P_SPORT0_RFS, P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0} | ||
37 | |||
38 | #define PIN_REQ_SPORT_1 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, \ | ||
39 | P_SPORT1_RFS, P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0} | ||
40 | |||
41 | #define PIN_REQ_SPORT_2 {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, \ | ||
42 | P_SPORT2_RFS, P_SPORT2_DRPRI, P_SPORT2_RSCLK, 0} | ||
43 | |||
44 | #define PIN_REQ_SPORT_3 {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, \ | ||
45 | P_SPORT3_RFS, P_SPORT3_DRPRI, P_SPORT3_RSCLK, 0} | ||
46 | #else | ||
47 | #define PIN_REQ_SPORT_0 {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \ | ||
48 | P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0} | ||
49 | |||
50 | #define PIN_REQ_SPORT_1 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \ | ||
51 | P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0} | ||
52 | #endif | ||
53 | |||
54 | static int *cmd_count; | 34 | static int *cmd_count; |
55 | static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; | 35 | static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; |
56 | 36 | ||
37 | #define SPORT_REQ(x) \ | ||
38 | [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \ | ||
39 | P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0} | ||
57 | static u16 sport_req[][7] = { | 40 | static u16 sport_req[][7] = { |
58 | PIN_REQ_SPORT_0, | 41 | #ifdef SPORT0_TCR1 |
59 | #ifdef PIN_REQ_SPORT_1 | 42 | SPORT_REQ(0), |
60 | PIN_REQ_SPORT_1, | ||
61 | #endif | 43 | #endif |
62 | #ifdef PIN_REQ_SPORT_2 | 44 | #ifdef SPORT1_TCR1 |
63 | PIN_REQ_SPORT_2, | 45 | SPORT_REQ(1), |
64 | #endif | 46 | #endif |
65 | #ifdef PIN_REQ_SPORT_3 | 47 | #ifdef SPORT2_TCR1 |
66 | PIN_REQ_SPORT_3, | 48 | SPORT_REQ(2), |
67 | #endif | 49 | #endif |
68 | }; | 50 | #ifdef SPORT3_TCR1 |
51 | SPORT_REQ(3), | ||
52 | #endif | ||
53 | }; | ||
69 | 54 | ||
55 | #define SPORT_PARAMS(x) \ | ||
56 | [x] = { \ | ||
57 | .dma_rx_chan = CH_SPORT##x##_RX, \ | ||
58 | .dma_tx_chan = CH_SPORT##x##_TX, \ | ||
59 | .err_irq = IRQ_SPORT##x##_ERROR, \ | ||
60 | .regs = (struct sport_register *)SPORT##x##_TCR1, \ | ||
61 | } | ||
70 | static struct sport_param sport_params[4] = { | 62 | static struct sport_param sport_params[4] = { |
71 | { | 63 | #ifdef SPORT0_TCR1 |
72 | .dma_rx_chan = CH_SPORT0_RX, | 64 | SPORT_PARAMS(0), |
73 | .dma_tx_chan = CH_SPORT0_TX, | ||
74 | .err_irq = IRQ_SPORT0_ERROR, | ||
75 | .regs = (struct sport_register *)SPORT0_TCR1, | ||
76 | }, | ||
77 | #ifdef PIN_REQ_SPORT_1 | ||
78 | { | ||
79 | .dma_rx_chan = CH_SPORT1_RX, | ||
80 | .dma_tx_chan = CH_SPORT1_TX, | ||
81 | .err_irq = IRQ_SPORT1_ERROR, | ||
82 | .regs = (struct sport_register *)SPORT1_TCR1, | ||
83 | }, | ||
84 | #endif | 65 | #endif |
85 | #ifdef PIN_REQ_SPORT_2 | 66 | #ifdef SPORT1_TCR1 |
86 | { | 67 | SPORT_PARAMS(1), |
87 | .dma_rx_chan = CH_SPORT2_RX, | ||
88 | .dma_tx_chan = CH_SPORT2_TX, | ||
89 | .err_irq = IRQ_SPORT2_ERROR, | ||
90 | .regs = (struct sport_register *)SPORT2_TCR1, | ||
91 | }, | ||
92 | #endif | 68 | #endif |
93 | #ifdef PIN_REQ_SPORT_3 | 69 | #ifdef SPORT2_TCR1 |
94 | { | 70 | SPORT_PARAMS(2), |
95 | .dma_rx_chan = CH_SPORT3_RX, | 71 | #endif |
96 | .dma_tx_chan = CH_SPORT3_TX, | 72 | #ifdef SPORT3_TCR1 |
97 | .err_irq = IRQ_SPORT3_ERROR, | 73 | SPORT_PARAMS(3), |
98 | .regs = (struct sport_register *)SPORT3_TCR1, | ||
99 | } | ||
100 | #endif | 74 | #endif |
101 | }; | 75 | }; |
102 | 76 | ||
@@ -332,11 +306,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev, | |||
332 | if (cmd_count == NULL) | 306 | if (cmd_count == NULL) |
333 | return -ENOMEM; | 307 | return -ENOMEM; |
334 | 308 | ||
335 | if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { | 309 | if (peripheral_request_list(sport_req[sport_num], "soc-audio")) { |
336 | pr_err("Requesting Peripherals failed\n"); | 310 | pr_err("Requesting Peripherals failed\n"); |
337 | ret = -EFAULT; | 311 | ret = -EFAULT; |
338 | goto peripheral_err; | 312 | goto peripheral_err; |
339 | } | 313 | } |
340 | 314 | ||
341 | #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET | 315 | #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET |
342 | /* Request PB3 as reset pin */ | 316 | /* Request PB3 as reset pin */ |
@@ -385,7 +359,7 @@ sport_err: | |||
385 | gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); | 359 | gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); |
386 | #endif | 360 | #endif |
387 | gpio_err: | 361 | gpio_err: |
388 | peripheral_free_list(&sport_req[sport_num][0]); | 362 | peripheral_free_list(sport_req[sport_num]); |
389 | peripheral_err: | 363 | peripheral_err: |
390 | free_page((unsigned long)cmd_count); | 364 | free_page((unsigned long)cmd_count); |
391 | cmd_count = NULL; | 365 | cmd_count = NULL; |
@@ -398,7 +372,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev, | |||
398 | { | 372 | { |
399 | free_page((unsigned long)cmd_count); | 373 | free_page((unsigned long)cmd_count); |
400 | cmd_count = NULL; | 374 | cmd_count = NULL; |
401 | peripheral_free_list(&sport_req[sport_num][0]); | 375 | peripheral_free_list(sport_req[sport_num]); |
402 | #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET | 376 | #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET |
403 | gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); | 377 | gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); |
404 | #endif | 378 | #endif |
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 53d290b3ea47..1318c4f627b7 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c | |||
@@ -184,7 +184,7 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream, | |||
184 | return 0 ; | 184 | return 0 ; |
185 | } | 185 | } |
186 | 186 | ||
187 | struct snd_pcm_ops bf5xx_pcm_i2s_ops = { | 187 | static struct snd_pcm_ops bf5xx_pcm_i2s_ops = { |
188 | .open = bf5xx_pcm_open, | 188 | .open = bf5xx_pcm_open, |
189 | .ioctl = snd_pcm_lib_ioctl, | 189 | .ioctl = snd_pcm_lib_ioctl, |
190 | .hw_params = bf5xx_pcm_hw_params, | 190 | .hw_params = bf5xx_pcm_hw_params, |
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c index 3b99e484d555..b7953c8cf838 100644 --- a/sound/soc/blackfin/bf5xx-sport.c +++ b/sound/soc/blackfin/bf5xx-sport.c | |||
@@ -133,7 +133,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount, | |||
133 | int i; | 133 | int i; |
134 | 134 | ||
135 | for (i = 0; i < fragcount; ++i) { | 135 | for (i = 0; i < fragcount; ++i) { |
136 | desc[i].next_desc_addr = (unsigned long)&(desc[i + 1]); | 136 | desc[i].next_desc_addr = &(desc[i + 1]); |
137 | desc[i].start_addr = (unsigned long)buf + i*fragsize; | 137 | desc[i].start_addr = (unsigned long)buf + i*fragsize; |
138 | desc[i].cfg = cfg; | 138 | desc[i].cfg = cfg; |
139 | desc[i].x_count = x_count; | 139 | desc[i].x_count = x_count; |
@@ -143,12 +143,12 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount, | |||
143 | } | 143 | } |
144 | 144 | ||
145 | /* make circular */ | 145 | /* make circular */ |
146 | desc[fragcount-1].next_desc_addr = (unsigned long)desc; | 146 | desc[fragcount-1].next_desc_addr = desc; |
147 | 147 | ||
148 | pr_debug("setup desc: desc0=%p, next0=%lx, desc1=%p," | 148 | pr_debug("setup desc: desc0=%p, next0=%p, desc1=%p," |
149 | "next1=%lx\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n", | 149 | "next1=%p\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n", |
150 | &(desc[0]), desc[0].next_desc_addr, | 150 | desc, desc[0].next_desc_addr, |
151 | &(desc[1]), desc[1].next_desc_addr, | 151 | desc+1, desc[1].next_desc_addr, |
152 | desc[0].x_count, desc[0].y_count, | 152 | desc[0].x_count, desc[0].y_count, |
153 | desc[0].start_addr, desc[0].cfg); | 153 | desc[0].start_addr, desc[0].cfg); |
154 | } | 154 | } |
@@ -184,22 +184,20 @@ static inline int sport_hook_rx_dummy(struct sport_device *sport) | |||
184 | BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc); | 184 | BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc); |
185 | 185 | ||
186 | /* Maybe the dummy buffer descriptor ring is damaged */ | 186 | /* Maybe the dummy buffer descriptor ring is damaged */ |
187 | sport->dummy_rx_desc->next_desc_addr = \ | 187 | sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc + 1; |
188 | (unsigned long)(sport->dummy_rx_desc+1); | ||
189 | 188 | ||
190 | local_irq_save(flags); | 189 | local_irq_save(flags); |
191 | desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_rx_chan); | 190 | desc = get_dma_next_desc_ptr(sport->dma_rx_chan); |
192 | /* Copy the descriptor which will be damaged to backup */ | 191 | /* Copy the descriptor which will be damaged to backup */ |
193 | temp_desc = *desc; | 192 | temp_desc = *desc; |
194 | desc->x_count = 0xa; | 193 | desc->x_count = 0xa; |
195 | desc->y_count = 0; | 194 | desc->y_count = 0; |
196 | desc->next_desc_addr = (unsigned long)(sport->dummy_rx_desc); | 195 | desc->next_desc_addr = sport->dummy_rx_desc; |
197 | local_irq_restore(flags); | 196 | local_irq_restore(flags); |
198 | /* Waiting for dummy buffer descriptor is already hooked*/ | 197 | /* Waiting for dummy buffer descriptor is already hooked*/ |
199 | while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - | 198 | while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - |
200 | sizeof(struct dmasg)) != | 199 | sizeof(struct dmasg)) != sport->dummy_rx_desc) |
201 | (unsigned long)sport->dummy_rx_desc) | 200 | continue; |
202 | ; | ||
203 | sport->curr_rx_desc = sport->dummy_rx_desc; | 201 | sport->curr_rx_desc = sport->dummy_rx_desc; |
204 | /* Restore the damaged descriptor */ | 202 | /* Restore the damaged descriptor */ |
205 | *desc = temp_desc; | 203 | *desc = temp_desc; |
@@ -210,14 +208,12 @@ static inline int sport_hook_rx_dummy(struct sport_device *sport) | |||
210 | static inline int sport_rx_dma_start(struct sport_device *sport, int dummy) | 208 | static inline int sport_rx_dma_start(struct sport_device *sport, int dummy) |
211 | { | 209 | { |
212 | if (dummy) { | 210 | if (dummy) { |
213 | sport->dummy_rx_desc->next_desc_addr = \ | 211 | sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc; |
214 | (unsigned long) sport->dummy_rx_desc; | ||
215 | sport->curr_rx_desc = sport->dummy_rx_desc; | 212 | sport->curr_rx_desc = sport->dummy_rx_desc; |
216 | } else | 213 | } else |
217 | sport->curr_rx_desc = sport->dma_rx_desc; | 214 | sport->curr_rx_desc = sport->dma_rx_desc; |
218 | 215 | ||
219 | set_dma_next_desc_addr(sport->dma_rx_chan, \ | 216 | set_dma_next_desc_addr(sport->dma_rx_chan, sport->curr_rx_desc); |
220 | (unsigned long)(sport->curr_rx_desc)); | ||
221 | set_dma_x_count(sport->dma_rx_chan, 0); | 217 | set_dma_x_count(sport->dma_rx_chan, 0); |
222 | set_dma_x_modify(sport->dma_rx_chan, 0); | 218 | set_dma_x_modify(sport->dma_rx_chan, 0); |
223 | set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \ | 219 | set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \ |
@@ -231,14 +227,12 @@ static inline int sport_rx_dma_start(struct sport_device *sport, int dummy) | |||
231 | static inline int sport_tx_dma_start(struct sport_device *sport, int dummy) | 227 | static inline int sport_tx_dma_start(struct sport_device *sport, int dummy) |
232 | { | 228 | { |
233 | if (dummy) { | 229 | if (dummy) { |
234 | sport->dummy_tx_desc->next_desc_addr = \ | 230 | sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc; |
235 | (unsigned long) sport->dummy_tx_desc; | ||
236 | sport->curr_tx_desc = sport->dummy_tx_desc; | 231 | sport->curr_tx_desc = sport->dummy_tx_desc; |
237 | } else | 232 | } else |
238 | sport->curr_tx_desc = sport->dma_tx_desc; | 233 | sport->curr_tx_desc = sport->dma_tx_desc; |
239 | 234 | ||
240 | set_dma_next_desc_addr(sport->dma_tx_chan, \ | 235 | set_dma_next_desc_addr(sport->dma_tx_chan, sport->curr_tx_desc); |
241 | (unsigned long)(sport->curr_tx_desc)); | ||
242 | set_dma_x_count(sport->dma_tx_chan, 0); | 236 | set_dma_x_count(sport->dma_tx_chan, 0); |
243 | set_dma_x_modify(sport->dma_tx_chan, 0); | 237 | set_dma_x_modify(sport->dma_tx_chan, 0); |
244 | set_dma_config(sport->dma_tx_chan, | 238 | set_dma_config(sport->dma_tx_chan, |
@@ -261,11 +255,9 @@ int sport_rx_start(struct sport_device *sport) | |||
261 | BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc); | 255 | BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc); |
262 | local_irq_save(flags); | 256 | local_irq_save(flags); |
263 | while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - | 257 | while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - |
264 | sizeof(struct dmasg)) != | 258 | sizeof(struct dmasg)) != sport->dummy_rx_desc) |
265 | (unsigned long)sport->dummy_rx_desc) | 259 | continue; |
266 | ; | 260 | sport->dummy_rx_desc->next_desc_addr = sport->dma_rx_desc; |
267 | sport->dummy_rx_desc->next_desc_addr = | ||
268 | (unsigned long)(sport->dma_rx_desc); | ||
269 | local_irq_restore(flags); | 261 | local_irq_restore(flags); |
270 | sport->curr_rx_desc = sport->dma_rx_desc; | 262 | sport->curr_rx_desc = sport->dma_rx_desc; |
271 | } else { | 263 | } else { |
@@ -310,23 +302,21 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport) | |||
310 | BUG_ON(sport->dummy_tx_desc == NULL); | 302 | BUG_ON(sport->dummy_tx_desc == NULL); |
311 | BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc); | 303 | BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc); |
312 | 304 | ||
313 | sport->dummy_tx_desc->next_desc_addr = \ | 305 | sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc + 1; |
314 | (unsigned long)(sport->dummy_tx_desc+1); | ||
315 | 306 | ||
316 | /* Shorten the time on last normal descriptor */ | 307 | /* Shorten the time on last normal descriptor */ |
317 | local_irq_save(flags); | 308 | local_irq_save(flags); |
318 | desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_tx_chan); | 309 | desc = get_dma_next_desc_ptr(sport->dma_tx_chan); |
319 | /* Store the descriptor which will be damaged */ | 310 | /* Store the descriptor which will be damaged */ |
320 | temp_desc = *desc; | 311 | temp_desc = *desc; |
321 | desc->x_count = 0xa; | 312 | desc->x_count = 0xa; |
322 | desc->y_count = 0; | 313 | desc->y_count = 0; |
323 | desc->next_desc_addr = (unsigned long)(sport->dummy_tx_desc); | 314 | desc->next_desc_addr = sport->dummy_tx_desc; |
324 | local_irq_restore(flags); | 315 | local_irq_restore(flags); |
325 | /* Waiting for dummy buffer descriptor is already hooked*/ | 316 | /* Waiting for dummy buffer descriptor is already hooked*/ |
326 | while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \ | 317 | while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \ |
327 | sizeof(struct dmasg)) != \ | 318 | sizeof(struct dmasg)) != sport->dummy_tx_desc) |
328 | (unsigned long)sport->dummy_tx_desc) | 319 | continue; |
329 | ; | ||
330 | sport->curr_tx_desc = sport->dummy_tx_desc; | 320 | sport->curr_tx_desc = sport->dummy_tx_desc; |
331 | /* Restore the damaged descriptor */ | 321 | /* Restore the damaged descriptor */ |
332 | *desc = temp_desc; | 322 | *desc = temp_desc; |
@@ -347,11 +337,9 @@ int sport_tx_start(struct sport_device *sport) | |||
347 | /* Hook the normal buffer descriptor */ | 337 | /* Hook the normal buffer descriptor */ |
348 | local_irq_save(flags); | 338 | local_irq_save(flags); |
349 | while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - | 339 | while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - |
350 | sizeof(struct dmasg)) != | 340 | sizeof(struct dmasg)) != sport->dummy_tx_desc) |
351 | (unsigned long)sport->dummy_tx_desc) | 341 | continue; |
352 | ; | 342 | sport->dummy_tx_desc->next_desc_addr = sport->dma_tx_desc; |
353 | sport->dummy_tx_desc->next_desc_addr = | ||
354 | (unsigned long)(sport->dma_tx_desc); | ||
355 | local_irq_restore(flags); | 343 | local_irq_restore(flags); |
356 | sport->curr_tx_desc = sport->dma_tx_desc; | 344 | sport->curr_tx_desc = sport->dma_tx_desc; |
357 | } else { | 345 | } else { |
@@ -536,19 +524,17 @@ static int sport_config_rx_dummy(struct sport_device *sport) | |||
536 | unsigned config; | 524 | unsigned config; |
537 | 525 | ||
538 | pr_debug("%s entered\n", __func__); | 526 | pr_debug("%s entered\n", __func__); |
539 | #if L1_DATA_A_LENGTH != 0 | 527 | if (L1_DATA_A_LENGTH) |
540 | desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc)); | 528 | desc = l1_data_sram_zalloc(2 * sizeof(*desc)); |
541 | #else | 529 | else { |
542 | { | ||
543 | dma_addr_t addr; | 530 | dma_addr_t addr; |
544 | desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0); | 531 | desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0); |
532 | memset(desc, 0, 2 * sizeof(*desc)); | ||
545 | } | 533 | } |
546 | #endif | ||
547 | if (desc == NULL) { | 534 | if (desc == NULL) { |
548 | pr_err("Failed to allocate memory for dummy rx desc\n"); | 535 | pr_err("Failed to allocate memory for dummy rx desc\n"); |
549 | return -ENOMEM; | 536 | return -ENOMEM; |
550 | } | 537 | } |
551 | memset(desc, 0, 2 * sizeof(*desc)); | ||
552 | sport->dummy_rx_desc = desc; | 538 | sport->dummy_rx_desc = desc; |
553 | desc->start_addr = (unsigned long)sport->dummy_buf; | 539 | desc->start_addr = (unsigned long)sport->dummy_buf; |
554 | config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize) | 540 | config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize) |
@@ -559,8 +545,8 @@ static int sport_config_rx_dummy(struct sport_device *sport) | |||
559 | desc->y_count = 0; | 545 | desc->y_count = 0; |
560 | desc->y_modify = 0; | 546 | desc->y_modify = 0; |
561 | memcpy(desc+1, desc, sizeof(*desc)); | 547 | memcpy(desc+1, desc, sizeof(*desc)); |
562 | desc->next_desc_addr = (unsigned long)(desc+1); | 548 | desc->next_desc_addr = desc + 1; |
563 | desc[1].next_desc_addr = (unsigned long)desc; | 549 | desc[1].next_desc_addr = desc; |
564 | return 0; | 550 | return 0; |
565 | } | 551 | } |
566 | 552 | ||
@@ -571,19 +557,17 @@ static int sport_config_tx_dummy(struct sport_device *sport) | |||
571 | 557 | ||
572 | pr_debug("%s entered\n", __func__); | 558 | pr_debug("%s entered\n", __func__); |
573 | 559 | ||
574 | #if L1_DATA_A_LENGTH != 0 | 560 | if (L1_DATA_A_LENGTH) |
575 | desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc)); | 561 | desc = l1_data_sram_zalloc(2 * sizeof(*desc)); |
576 | #else | 562 | else { |
577 | { | ||
578 | dma_addr_t addr; | 563 | dma_addr_t addr; |
579 | desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0); | 564 | desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0); |
565 | memset(desc, 0, 2 * sizeof(*desc)); | ||
580 | } | 566 | } |
581 | #endif | ||
582 | if (!desc) { | 567 | if (!desc) { |
583 | pr_err("Failed to allocate memory for dummy tx desc\n"); | 568 | pr_err("Failed to allocate memory for dummy tx desc\n"); |
584 | return -ENOMEM; | 569 | return -ENOMEM; |
585 | } | 570 | } |
586 | memset(desc, 0, 2 * sizeof(*desc)); | ||
587 | sport->dummy_tx_desc = desc; | 571 | sport->dummy_tx_desc = desc; |
588 | desc->start_addr = (unsigned long)sport->dummy_buf + \ | 572 | desc->start_addr = (unsigned long)sport->dummy_buf + \ |
589 | sport->dummy_count; | 573 | sport->dummy_count; |
@@ -595,8 +579,8 @@ static int sport_config_tx_dummy(struct sport_device *sport) | |||
595 | desc->y_count = 0; | 579 | desc->y_count = 0; |
596 | desc->y_modify = 0; | 580 | desc->y_modify = 0; |
597 | memcpy(desc+1, desc, sizeof(*desc)); | 581 | memcpy(desc+1, desc, sizeof(*desc)); |
598 | desc->next_desc_addr = (unsigned long)(desc+1); | 582 | desc->next_desc_addr = desc + 1; |
599 | desc[1].next_desc_addr = (unsigned long)desc; | 583 | desc[1].next_desc_addr = desc; |
600 | return 0; | 584 | return 0; |
601 | } | 585 | } |
602 | 586 | ||
@@ -872,17 +856,15 @@ struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, | |||
872 | sport->wdsize = wdsize; | 856 | sport->wdsize = wdsize; |
873 | sport->dummy_count = dummy_count; | 857 | sport->dummy_count = dummy_count; |
874 | 858 | ||
875 | #if L1_DATA_A_LENGTH != 0 | 859 | if (L1_DATA_A_LENGTH) |
876 | sport->dummy_buf = l1_data_sram_alloc(dummy_count * 2); | 860 | sport->dummy_buf = l1_data_sram_zalloc(dummy_count * 2); |
877 | #else | 861 | else |
878 | sport->dummy_buf = kmalloc(dummy_count * 2, GFP_KERNEL); | 862 | sport->dummy_buf = kzalloc(dummy_count * 2, GFP_KERNEL); |
879 | #endif | ||
880 | if (sport->dummy_buf == NULL) { | 863 | if (sport->dummy_buf == NULL) { |
881 | pr_err("Failed to allocate dummy buffer\n"); | 864 | pr_err("Failed to allocate dummy buffer\n"); |
882 | goto __error; | 865 | goto __error; |
883 | } | 866 | } |
884 | 867 | ||
885 | memset(sport->dummy_buf, 0, dummy_count * 2); | ||
886 | ret = sport_config_rx_dummy(sport); | 868 | ret = sport_config_rx_dummy(sport); |
887 | if (ret) { | 869 | if (ret) { |
888 | pr_err("Failed to config rx dummy ring\n"); | 870 | pr_err("Failed to config rx dummy ring\n"); |
@@ -939,6 +921,7 @@ void sport_done(struct sport_device *sport) | |||
939 | sport = NULL; | 921 | sport = NULL; |
940 | } | 922 | } |
941 | EXPORT_SYMBOL(sport_done); | 923 | EXPORT_SYMBOL(sport_done); |
924 | |||
942 | /* | 925 | /* |
943 | * It is only used to send several bytes when dma is not enabled | 926 | * It is only used to send several bytes when dma is not enabled |
944 | * sport controller is configured but not enabled. | 927 | * sport controller is configured but not enabled. |
@@ -1029,4 +1012,3 @@ EXPORT_SYMBOL(sport_send_and_recv); | |||
1029 | MODULE_AUTHOR("Roy Huang"); | 1012 | MODULE_AUTHOR("Roy Huang"); |
1030 | MODULE_DESCRIPTION("SPORT driver for ADI Blackfin"); | 1013 | MODULE_DESCRIPTION("SPORT driver for ADI Blackfin"); |
1031 | MODULE_LICENSE("GPL"); | 1014 | MODULE_LICENSE("GPL"); |
1032 | |||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index d0e0d691ae51..a195303603e0 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -10,6 +10,7 @@ config SND_SOC_I2C_AND_SPI | |||
10 | 10 | ||
11 | config SND_SOC_ALL_CODECS | 11 | config SND_SOC_ALL_CODECS |
12 | tristate "Build all ASoC CODEC drivers" | 12 | tristate "Build all ASoC CODEC drivers" |
13 | select SND_SOC_L3 | ||
13 | select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS | 14 | select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS |
14 | select SND_SOC_AD1980 if SND_SOC_AC97_BUS | 15 | select SND_SOC_AD1980 if SND_SOC_AC97_BUS |
15 | select SND_SOC_AD73311 if I2C | 16 | select SND_SOC_AD73311 if I2C |
@@ -34,6 +35,7 @@ config SND_SOC_ALL_CODECS | |||
34 | select SND_SOC_WM8903 if I2C | 35 | select SND_SOC_WM8903 if I2C |
35 | select SND_SOC_WM8971 if I2C | 36 | select SND_SOC_WM8971 if I2C |
36 | select SND_SOC_WM8990 if I2C | 37 | select SND_SOC_WM8990 if I2C |
38 | select SND_SOC_WM9705 if SND_SOC_AC97_BUS | ||
37 | select SND_SOC_WM9712 if SND_SOC_AC97_BUS | 39 | select SND_SOC_WM9712 if SND_SOC_AC97_BUS |
38 | select SND_SOC_WM9713 if SND_SOC_AC97_BUS | 40 | select SND_SOC_WM9713 if SND_SOC_AC97_BUS |
39 | help | 41 | help |
@@ -90,7 +92,6 @@ config SND_SOC_SSM2602 | |||
90 | 92 | ||
91 | config SND_SOC_TLV320AIC23 | 93 | config SND_SOC_TLV320AIC23 |
92 | tristate | 94 | tristate |
93 | depends on I2C | ||
94 | 95 | ||
95 | config SND_SOC_TLV320AIC26 | 96 | config SND_SOC_TLV320AIC26 |
96 | tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE | 97 | tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE |
@@ -98,15 +99,12 @@ config SND_SOC_TLV320AIC26 | |||
98 | 99 | ||
99 | config SND_SOC_TLV320AIC3X | 100 | config SND_SOC_TLV320AIC3X |
100 | tristate | 101 | tristate |
101 | depends on I2C | ||
102 | 102 | ||
103 | config SND_SOC_TWL4030 | 103 | config SND_SOC_TWL4030 |
104 | tristate | 104 | tristate |
105 | depends on TWL4030_CORE | ||
106 | 105 | ||
107 | config SND_SOC_UDA134X | 106 | config SND_SOC_UDA134X |
108 | tristate | 107 | tristate |
109 | select SND_SOC_L3 | ||
110 | 108 | ||
111 | config SND_SOC_UDA1380 | 109 | config SND_SOC_UDA1380 |
112 | tristate | 110 | tristate |
@@ -144,6 +142,9 @@ config SND_SOC_WM8971 | |||
144 | config SND_SOC_WM8990 | 142 | config SND_SOC_WM8990 |
145 | tristate | 143 | tristate |
146 | 144 | ||
145 | config SND_SOC_WM9705 | ||
146 | tristate | ||
147 | |||
147 | config SND_SOC_WM9712 | 148 | config SND_SOC_WM9712 |
148 | tristate | 149 | tristate |
149 | 150 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index c4ddc9aa2bbd..3664cdc300b2 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -23,6 +23,7 @@ snd-soc-wm8900-objs := wm8900.o | |||
23 | snd-soc-wm8903-objs := wm8903.o | 23 | snd-soc-wm8903-objs := wm8903.o |
24 | snd-soc-wm8971-objs := wm8971.o | 24 | snd-soc-wm8971-objs := wm8971.o |
25 | snd-soc-wm8990-objs := wm8990.o | 25 | snd-soc-wm8990-objs := wm8990.o |
26 | snd-soc-wm9705-objs := wm9705.o | ||
26 | snd-soc-wm9712-objs := wm9712.o | 27 | snd-soc-wm9712-objs := wm9712.o |
27 | snd-soc-wm9713-objs := wm9713.o | 28 | snd-soc-wm9713-objs := wm9713.o |
28 | 29 | ||
@@ -51,5 +52,7 @@ obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o | |||
51 | obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o | 52 | obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o |
52 | obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o | 53 | obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o |
53 | obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o | 54 | obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o |
55 | obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o | ||
56 | obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o | ||
54 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o | 57 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o |
55 | obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o | 58 | obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o |
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index fb53e6511af2..11f84b6e5cb8 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c | |||
@@ -30,7 +30,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream, | |||
30 | struct snd_pcm_runtime *runtime = substream->runtime; | 30 | struct snd_pcm_runtime *runtime = substream->runtime; |
31 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 31 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
32 | struct snd_soc_device *socdev = rtd->socdev; | 32 | struct snd_soc_device *socdev = rtd->socdev; |
33 | struct snd_soc_codec *codec = socdev->codec; | 33 | struct snd_soc_codec *codec = socdev->card->codec; |
34 | 34 | ||
35 | int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | 35 | int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
36 | AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; | 36 | AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; |
@@ -84,10 +84,10 @@ static int ac97_soc_probe(struct platform_device *pdev) | |||
84 | 84 | ||
85 | printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); | 85 | printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); |
86 | 86 | ||
87 | socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 87 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); |
88 | if (!socdev->codec) | 88 | if (!socdev->card->codec) |
89 | return -ENOMEM; | 89 | return -ENOMEM; |
90 | codec = socdev->codec; | 90 | codec = socdev->card->codec; |
91 | mutex_init(&codec->mutex); | 91 | mutex_init(&codec->mutex); |
92 | 92 | ||
93 | codec->name = "AC97"; | 93 | codec->name = "AC97"; |
@@ -123,23 +123,21 @@ bus_err: | |||
123 | snd_soc_free_pcms(socdev); | 123 | snd_soc_free_pcms(socdev); |
124 | 124 | ||
125 | err: | 125 | err: |
126 | kfree(socdev->codec->reg_cache); | 126 | kfree(socdev->card->codec); |
127 | kfree(socdev->codec); | 127 | socdev->card->codec = NULL; |
128 | socdev->codec = NULL; | ||
129 | return ret; | 128 | return ret; |
130 | } | 129 | } |
131 | 130 | ||
132 | static int ac97_soc_remove(struct platform_device *pdev) | 131 | static int ac97_soc_remove(struct platform_device *pdev) |
133 | { | 132 | { |
134 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 133 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
135 | struct snd_soc_codec *codec = socdev->codec; | 134 | struct snd_soc_codec *codec = socdev->card->codec; |
136 | 135 | ||
137 | if (!codec) | 136 | if (!codec) |
138 | return 0; | 137 | return 0; |
139 | 138 | ||
140 | snd_soc_free_pcms(socdev); | 139 | snd_soc_free_pcms(socdev); |
141 | kfree(socdev->codec->reg_cache); | 140 | kfree(socdev->card->codec); |
142 | kfree(socdev->codec); | ||
143 | 141 | ||
144 | return 0; | 142 | return 0; |
145 | } | 143 | } |
@@ -149,7 +147,7 @@ static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg) | |||
149 | { | 147 | { |
150 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 148 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
151 | 149 | ||
152 | snd_ac97_suspend(socdev->codec->ac97); | 150 | snd_ac97_suspend(socdev->card->codec->ac97); |
153 | 151 | ||
154 | return 0; | 152 | return 0; |
155 | } | 153 | } |
@@ -158,7 +156,7 @@ static int ac97_soc_resume(struct platform_device *pdev) | |||
158 | { | 156 | { |
159 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 157 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
160 | 158 | ||
161 | snd_ac97_resume(socdev->codec->ac97); | 159 | snd_ac97_resume(socdev->card->codec->ac97); |
162 | 160 | ||
163 | return 0; | 161 | return 0; |
164 | } | 162 | } |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 73fdbb4d4a3d..ddb3b08ac23c 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -93,20 +93,6 @@ SOC_ENUM("Capture Source", ad1980_cap_src), | |||
93 | SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0), | 93 | SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0), |
94 | }; | 94 | }; |
95 | 95 | ||
96 | /* add non dapm controls */ | ||
97 | static int ad1980_add_controls(struct snd_soc_codec *codec) | ||
98 | { | ||
99 | int err, i; | ||
100 | |||
101 | for (i = 0; i < ARRAY_SIZE(ad1980_snd_ac97_controls); i++) { | ||
102 | err = snd_ctl_add(codec->card, snd_soc_cnew( | ||
103 | &ad1980_snd_ac97_controls[i], codec, NULL)); | ||
104 | if (err < 0) | ||
105 | return err; | ||
106 | } | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static unsigned int ac97_read(struct snd_soc_codec *codec, | 96 | static unsigned int ac97_read(struct snd_soc_codec *codec, |
111 | unsigned int reg) | 97 | unsigned int reg) |
112 | { | 98 | { |
@@ -123,7 +109,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, | |||
123 | default: | 109 | default: |
124 | reg = reg >> 1; | 110 | reg = reg >> 1; |
125 | 111 | ||
126 | if (reg >= (ARRAY_SIZE(ad1980_reg))) | 112 | if (reg >= ARRAY_SIZE(ad1980_reg)) |
127 | return -EINVAL; | 113 | return -EINVAL; |
128 | 114 | ||
129 | return cache[reg]; | 115 | return cache[reg]; |
@@ -137,7 +123,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, | |||
137 | 123 | ||
138 | soc_ac97_ops.write(codec->ac97, reg, val); | 124 | soc_ac97_ops.write(codec->ac97, reg, val); |
139 | reg = reg >> 1; | 125 | reg = reg >> 1; |
140 | if (reg < (ARRAY_SIZE(ad1980_reg))) | 126 | if (reg < ARRAY_SIZE(ad1980_reg)) |
141 | cache[reg] = val; | 127 | cache[reg] = val; |
142 | 128 | ||
143 | return 0; | 129 | return 0; |
@@ -200,10 +186,10 @@ static int ad1980_soc_probe(struct platform_device *pdev) | |||
200 | 186 | ||
201 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); | 187 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); |
202 | 188 | ||
203 | socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 189 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); |
204 | if (socdev->codec == NULL) | 190 | if (socdev->card->codec == NULL) |
205 | return -ENOMEM; | 191 | return -ENOMEM; |
206 | codec = socdev->codec; | 192 | codec = socdev->card->codec; |
207 | mutex_init(&codec->mutex); | 193 | mutex_init(&codec->mutex); |
208 | 194 | ||
209 | codec->reg_cache = | 195 | codec->reg_cache = |
@@ -269,7 +255,8 @@ static int ad1980_soc_probe(struct platform_device *pdev) | |||
269 | ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); | 255 | ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); |
270 | ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); | 256 | ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); |
271 | 257 | ||
272 | ad1980_add_controls(codec); | 258 | snd_soc_add_controls(codec, ad1980_snd_ac97_controls, |
259 | ARRAY_SIZE(ad1980_snd_ac97_controls)); | ||
273 | ret = snd_soc_init_card(socdev); | 260 | ret = snd_soc_init_card(socdev); |
274 | if (ret < 0) { | 261 | if (ret < 0) { |
275 | printk(KERN_ERR "ad1980: failed to register card\n"); | 262 | printk(KERN_ERR "ad1980: failed to register card\n"); |
@@ -288,15 +275,15 @@ codec_err: | |||
288 | kfree(codec->reg_cache); | 275 | kfree(codec->reg_cache); |
289 | 276 | ||
290 | cache_err: | 277 | cache_err: |
291 | kfree(socdev->codec); | 278 | kfree(socdev->card->codec); |
292 | socdev->codec = NULL; | 279 | socdev->card->codec = NULL; |
293 | return ret; | 280 | return ret; |
294 | } | 281 | } |
295 | 282 | ||
296 | static int ad1980_soc_remove(struct platform_device *pdev) | 283 | static int ad1980_soc_remove(struct platform_device *pdev) |
297 | { | 284 | { |
298 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 285 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
299 | struct snd_soc_codec *codec = socdev->codec; | 286 | struct snd_soc_codec *codec = socdev->card->codec; |
300 | 287 | ||
301 | if (codec == NULL) | 288 | if (codec == NULL) |
302 | return 0; | 289 | return 0; |
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index b09289a1e55a..e61dac5e7b8f 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c | |||
@@ -53,7 +53,7 @@ static int ad73311_soc_probe(struct platform_device *pdev) | |||
53 | codec->owner = THIS_MODULE; | 53 | codec->owner = THIS_MODULE; |
54 | codec->dai = &ad73311_dai; | 54 | codec->dai = &ad73311_dai; |
55 | codec->num_dai = 1; | 55 | codec->num_dai = 1; |
56 | socdev->codec = codec; | 56 | socdev->card->codec = codec; |
57 | INIT_LIST_HEAD(&codec->dapm_widgets); | 57 | INIT_LIST_HEAD(&codec->dapm_widgets); |
58 | INIT_LIST_HEAD(&codec->dapm_paths); | 58 | INIT_LIST_HEAD(&codec->dapm_paths); |
59 | 59 | ||
@@ -75,15 +75,15 @@ static int ad73311_soc_probe(struct platform_device *pdev) | |||
75 | register_err: | 75 | register_err: |
76 | snd_soc_free_pcms(socdev); | 76 | snd_soc_free_pcms(socdev); |
77 | pcm_err: | 77 | pcm_err: |
78 | kfree(socdev->codec); | 78 | kfree(socdev->card->codec); |
79 | socdev->codec = NULL; | 79 | socdev->card->codec = NULL; |
80 | return ret; | 80 | return ret; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int ad73311_soc_remove(struct platform_device *pdev) | 83 | static int ad73311_soc_remove(struct platform_device *pdev) |
84 | { | 84 | { |
85 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 85 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
86 | struct snd_soc_codec *codec = socdev->codec; | 86 | struct snd_soc_codec *codec = socdev->card->codec; |
87 | 87 | ||
88 | if (codec == NULL) | 88 | if (codec == NULL) |
89 | return 0; | 89 | return 0; |
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 81300d8d42ca..d56e6bb1fedb 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
@@ -155,21 +155,6 @@ static const struct snd_kcontrol_new ak4535_snd_controls[] = { | |||
155 | SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL, 4, 7, 0), | 155 | SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL, 4, 7, 0), |
156 | }; | 156 | }; |
157 | 157 | ||
158 | /* add non dapm controls */ | ||
159 | static int ak4535_add_controls(struct snd_soc_codec *codec) | ||
160 | { | ||
161 | int err, i; | ||
162 | |||
163 | for (i = 0; i < ARRAY_SIZE(ak4535_snd_controls); i++) { | ||
164 | err = snd_ctl_add(codec->card, | ||
165 | snd_soc_cnew(&ak4535_snd_controls[i], codec, NULL)); | ||
166 | if (err < 0) | ||
167 | return err; | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | /* Mono 1 Mixer */ | 158 | /* Mono 1 Mixer */ |
174 | static const struct snd_kcontrol_new ak4535_mono1_mixer_controls[] = { | 159 | static const struct snd_kcontrol_new ak4535_mono1_mixer_controls[] = { |
175 | SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1, 4, 1, 0), | 160 | SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1, 4, 1, 0), |
@@ -344,7 +329,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream, | |||
344 | { | 329 | { |
345 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 330 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
346 | struct snd_soc_device *socdev = rtd->socdev; | 331 | struct snd_soc_device *socdev = rtd->socdev; |
347 | struct snd_soc_codec *codec = socdev->codec; | 332 | struct snd_soc_codec *codec = socdev->card->codec; |
348 | struct ak4535_priv *ak4535 = codec->private_data; | 333 | struct ak4535_priv *ak4535 = codec->private_data; |
349 | u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); | 334 | u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); |
350 | int rate = params_rate(params), fs = 256; | 335 | int rate = params_rate(params), fs = 256; |
@@ -462,7 +447,7 @@ EXPORT_SYMBOL_GPL(ak4535_dai); | |||
462 | static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) | 447 | static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) |
463 | { | 448 | { |
464 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 449 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
465 | struct snd_soc_codec *codec = socdev->codec; | 450 | struct snd_soc_codec *codec = socdev->card->codec; |
466 | 451 | ||
467 | ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); | 452 | ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); |
468 | return 0; | 453 | return 0; |
@@ -471,7 +456,7 @@ static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) | |||
471 | static int ak4535_resume(struct platform_device *pdev) | 456 | static int ak4535_resume(struct platform_device *pdev) |
472 | { | 457 | { |
473 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 458 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
474 | struct snd_soc_codec *codec = socdev->codec; | 459 | struct snd_soc_codec *codec = socdev->card->codec; |
475 | ak4535_sync(codec); | 460 | ak4535_sync(codec); |
476 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 461 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
477 | ak4535_set_bias_level(codec, codec->suspend_bias_level); | 462 | ak4535_set_bias_level(codec, codec->suspend_bias_level); |
@@ -484,7 +469,7 @@ static int ak4535_resume(struct platform_device *pdev) | |||
484 | */ | 469 | */ |
485 | static int ak4535_init(struct snd_soc_device *socdev) | 470 | static int ak4535_init(struct snd_soc_device *socdev) |
486 | { | 471 | { |
487 | struct snd_soc_codec *codec = socdev->codec; | 472 | struct snd_soc_codec *codec = socdev->card->codec; |
488 | int ret = 0; | 473 | int ret = 0; |
489 | 474 | ||
490 | codec->name = "AK4535"; | 475 | codec->name = "AK4535"; |
@@ -510,7 +495,8 @@ static int ak4535_init(struct snd_soc_device *socdev) | |||
510 | /* power on device */ | 495 | /* power on device */ |
511 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 496 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
512 | 497 | ||
513 | ak4535_add_controls(codec); | 498 | snd_soc_add_controls(codec, ak4535_snd_controls, |
499 | ARRAY_SIZE(ak4535_snd_controls)); | ||
514 | ak4535_add_widgets(codec); | 500 | ak4535_add_widgets(codec); |
515 | ret = snd_soc_init_card(socdev); | 501 | ret = snd_soc_init_card(socdev); |
516 | if (ret < 0) { | 502 | if (ret < 0) { |
@@ -537,7 +523,7 @@ static int ak4535_i2c_probe(struct i2c_client *i2c, | |||
537 | const struct i2c_device_id *id) | 523 | const struct i2c_device_id *id) |
538 | { | 524 | { |
539 | struct snd_soc_device *socdev = ak4535_socdev; | 525 | struct snd_soc_device *socdev = ak4535_socdev; |
540 | struct snd_soc_codec *codec = socdev->codec; | 526 | struct snd_soc_codec *codec = socdev->card->codec; |
541 | int ret; | 527 | int ret; |
542 | 528 | ||
543 | i2c_set_clientdata(i2c, codec); | 529 | i2c_set_clientdata(i2c, codec); |
@@ -636,7 +622,7 @@ static int ak4535_probe(struct platform_device *pdev) | |||
636 | } | 622 | } |
637 | 623 | ||
638 | codec->private_data = ak4535; | 624 | codec->private_data = ak4535; |
639 | socdev->codec = codec; | 625 | socdev->card->codec = codec; |
640 | mutex_init(&codec->mutex); | 626 | mutex_init(&codec->mutex); |
641 | INIT_LIST_HEAD(&codec->dapm_widgets); | 627 | INIT_LIST_HEAD(&codec->dapm_widgets); |
642 | INIT_LIST_HEAD(&codec->dapm_paths); | 628 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -663,7 +649,7 @@ static int ak4535_probe(struct platform_device *pdev) | |||
663 | static int ak4535_remove(struct platform_device *pdev) | 649 | static int ak4535_remove(struct platform_device *pdev) |
664 | { | 650 | { |
665 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 651 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
666 | struct snd_soc_codec *codec = socdev->codec; | 652 | struct snd_soc_codec *codec = socdev->card->codec; |
667 | 653 | ||
668 | if (codec->control_data) | 654 | if (codec->control_data) |
669 | ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); | 655 | ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index f1aa0c34421c..2c79a24186fd 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -3,20 +3,16 @@ | |||
3 | * | 3 | * |
4 | * Author: Timur Tabi <timur@freescale.com> | 4 | * Author: Timur Tabi <timur@freescale.com> |
5 | * | 5 | * |
6 | * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under | 6 | * Copyright 2007-2009 Freescale Semiconductor, Inc. This file is licensed |
7 | * the terms of the GNU General Public License version 2. This program | 7 | * under the terms of the GNU General Public License version 2. This |
8 | * is licensed "as is" without any warranty of any kind, whether express | 8 | * program is licensed "as is" without any warranty of any kind, whether |
9 | * or implied. | 9 | * express or implied. |
10 | * | 10 | * |
11 | * This is an ASoC device driver for the Cirrus Logic CS4270 codec. | 11 | * This is an ASoC device driver for the Cirrus Logic CS4270 codec. |
12 | * | 12 | * |
13 | * Current features/limitations: | 13 | * Current features/limitations: |
14 | * | 14 | * |
15 | * 1) Software mode is supported. Stand-alone mode is automatically | 15 | * 1) Software mode is supported. Stand-alone mode is not supported. |
16 | * selected if I2C is disabled or if a CS4270 is not found on the I2C | ||
17 | * bus. However, stand-alone mode is only partially implemented because | ||
18 | * there is no mechanism yet for this driver and the machine driver to | ||
19 | * communicate the values of the M0, M1, MCLK1, and MCLK2 pins. | ||
20 | * 2) Only I2C is supported, not SPI | 16 | * 2) Only I2C is supported, not SPI |
21 | * 3) Only Master mode is supported, not Slave. | 17 | * 3) Only Master mode is supported, not Slave. |
22 | * 4) The machine driver's 'startup' function must call | 18 | * 4) The machine driver's 'startup' function must call |
@@ -35,18 +31,6 @@ | |||
35 | 31 | ||
36 | #include "cs4270.h" | 32 | #include "cs4270.h" |
37 | 33 | ||
38 | /* If I2C is defined, then we support software mode. However, if we're | ||
39 | not compiled as module but I2C is, then we can't use I2C calls. */ | ||
40 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
41 | #define USE_I2C | ||
42 | #endif | ||
43 | |||
44 | /* Private data for the CS4270 */ | ||
45 | struct cs4270_private { | ||
46 | unsigned int mclk; /* Input frequency of the MCLK pin */ | ||
47 | unsigned int mode; /* The mode (I2S or left-justified) */ | ||
48 | }; | ||
49 | |||
50 | /* | 34 | /* |
51 | * The codec isn't really big-endian or little-endian, since the I2S | 35 | * The codec isn't really big-endian or little-endian, since the I2S |
52 | * interface requires data to be sent serially with the MSbit first. | 36 | * interface requires data to be sent serially with the MSbit first. |
@@ -60,8 +44,6 @@ struct cs4270_private { | |||
60 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ | 44 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ |
61 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) | 45 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) |
62 | 46 | ||
63 | #ifdef USE_I2C | ||
64 | |||
65 | /* CS4270 registers addresses */ | 47 | /* CS4270 registers addresses */ |
66 | #define CS4270_CHIPID 0x01 /* Chip ID */ | 48 | #define CS4270_CHIPID 0x01 /* Chip ID */ |
67 | #define CS4270_PWRCTL 0x02 /* Power Control */ | 49 | #define CS4270_PWRCTL 0x02 /* Power Control */ |
@@ -121,8 +103,21 @@ struct cs4270_private { | |||
121 | #define CS4270_MUTE_DAC_A 0x01 | 103 | #define CS4270_MUTE_DAC_A 0x01 |
122 | #define CS4270_MUTE_DAC_B 0x02 | 104 | #define CS4270_MUTE_DAC_B 0x02 |
123 | 105 | ||
124 | /* | 106 | /* Private data for the CS4270 */ |
125 | * Clock Ratio Selection for Master Mode with I2C enabled | 107 | struct cs4270_private { |
108 | struct snd_soc_codec codec; | ||
109 | u8 reg_cache[CS4270_NUMREGS]; | ||
110 | unsigned int mclk; /* Input frequency of the MCLK pin */ | ||
111 | unsigned int mode; /* The mode (I2S or left-justified) */ | ||
112 | }; | ||
113 | |||
114 | /** | ||
115 | * struct cs4270_mode_ratios - clock ratio tables | ||
116 | * @ratio: the ratio of MCLK to the sample rate | ||
117 | * @speed_mode: the Speed Mode bits to set in the Mode Control register for | ||
118 | * this ratio | ||
119 | * @mclk: the Ratio Select bits to set in the Mode Control register for this | ||
120 | * ratio | ||
126 | * | 121 | * |
127 | * The data for this chart is taken from Table 5 of the CS4270 reference | 122 | * The data for this chart is taken from Table 5 of the CS4270 reference |
128 | * manual. | 123 | * manual. |
@@ -131,31 +126,30 @@ struct cs4270_private { | |||
131 | * It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling | 126 | * It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling |
132 | * rates the CS4270 currently supports. | 127 | * rates the CS4270 currently supports. |
133 | * | 128 | * |
134 | * Each element in this array corresponds to the ratios in mclk_ratios[]. | 129 | * @speed_mode is the corresponding bit pattern to be written to the |
135 | * These two arrays need to be in sync. | ||
136 | * | ||
137 | * 'speed_mode' is the corresponding bit pattern to be written to the | ||
138 | * MODE bits of the Mode Control Register | 130 | * MODE bits of the Mode Control Register |
139 | * | 131 | * |
140 | * 'mclk' is the corresponding bit pattern to be wirten to the MCLK bits of | 132 | * @mclk is the corresponding bit pattern to be wirten to the MCLK bits of |
141 | * the Mode Control Register. | 133 | * the Mode Control Register. |
142 | * | 134 | * |
143 | * In situations where a single ratio is represented by multiple speed | 135 | * In situations where a single ratio is represented by multiple speed |
144 | * modes, we favor the slowest speed. E.g, for a ratio of 128, we pick | 136 | * modes, we favor the slowest speed. E.g, for a ratio of 128, we pick |
145 | * double-speed instead of quad-speed. However, the CS4270 errata states | 137 | * double-speed instead of quad-speed. However, the CS4270 errata states |
146 | * that Divide-By-1.5 can cause failures, so we avoid that mode where | 138 | * that divide-By-1.5 can cause failures, so we avoid that mode where |
147 | * possible. | 139 | * possible. |
148 | * | 140 | * |
149 | * ERRATA: There is an errata for the CS4270 where divide-by-1.5 does not | 141 | * Errata: There is an errata for the CS4270 where divide-by-1.5 does not |
150 | * work if VD = 3.3V. If this effects you, select the | 142 | * work if Vd is 3.3V. If this effects you, select the |
151 | * CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will | 143 | * CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will |
152 | * never select any sample rates that require divide-by-1.5. | 144 | * never select any sample rates that require divide-by-1.5. |
153 | */ | 145 | */ |
154 | static struct { | 146 | struct cs4270_mode_ratios { |
155 | unsigned int ratio; | 147 | unsigned int ratio; |
156 | u8 speed_mode; | 148 | u8 speed_mode; |
157 | u8 mclk; | 149 | u8 mclk; |
158 | } cs4270_mode_ratios[] = { | 150 | }; |
151 | |||
152 | static struct cs4270_mode_ratios cs4270_mode_ratios[] = { | ||
159 | {64, CS4270_MODE_4X, CS4270_MODE_DIV1}, | 153 | {64, CS4270_MODE_4X, CS4270_MODE_DIV1}, |
160 | #ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA | 154 | #ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA |
161 | {96, CS4270_MODE_4X, CS4270_MODE_DIV15}, | 155 | {96, CS4270_MODE_4X, CS4270_MODE_DIV15}, |
@@ -172,34 +166,27 @@ static struct { | |||
172 | /* The number of MCLK/LRCK ratios supported by the CS4270 */ | 166 | /* The number of MCLK/LRCK ratios supported by the CS4270 */ |
173 | #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) | 167 | #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) |
174 | 168 | ||
175 | /* | 169 | /** |
176 | * Determine the CS4270 samples rates. | 170 | * cs4270_set_dai_sysclk - determine the CS4270 samples rates. |
171 | * @codec_dai: the codec DAI | ||
172 | * @clk_id: the clock ID (ignored) | ||
173 | * @freq: the MCLK input frequency | ||
174 | * @dir: the clock direction (ignored) | ||
177 | * | 175 | * |
178 | * 'freq' is the input frequency to MCLK. The other parameters are ignored. | 176 | * This function is used to tell the codec driver what the input MCLK |
177 | * frequency is. | ||
179 | * | 178 | * |
180 | * The value of MCLK is used to determine which sample rates are supported | 179 | * The value of MCLK is used to determine which sample rates are supported |
181 | * by the CS4270. The ratio of MCLK / Fs must be equal to one of nine | 180 | * by the CS4270. The ratio of MCLK / Fs must be equal to one of nine |
182 | * support values: 64, 96, 128, 192, 256, 384, 512, 768, and 1024. | 181 | * supported values - 64, 96, 128, 192, 256, 384, 512, 768, and 1024. |
183 | * | 182 | * |
184 | * This function calculates the nine ratios and determines which ones match | 183 | * This function calculates the nine ratios and determines which ones match |
185 | * a standard sample rate. If there's a match, then it is added to the list | 184 | * a standard sample rate. If there's a match, then it is added to the list |
186 | * of support sample rates. | 185 | * of supported sample rates. |
187 | * | 186 | * |
188 | * This function must be called by the machine driver's 'startup' function, | 187 | * This function must be called by the machine driver's 'startup' function, |
189 | * otherwise the list of supported sample rates will not be available in | 188 | * otherwise the list of supported sample rates will not be available in |
190 | * time for ALSA. | 189 | * time for ALSA. |
191 | * | ||
192 | * Note that in stand-alone mode, the sample rate is determined by input | ||
193 | * pins M0, M1, MDIV1, and MDIV2. Also in stand-alone mode, divide-by-3 | ||
194 | * is not a programmable option. However, divide-by-3 is not an available | ||
195 | * option in stand-alone mode. This cases two problems: a ratio of 768 is | ||
196 | * not available (it requires divide-by-3) and B) ratios 192 and 384 can | ||
197 | * only be selected with divide-by-1.5, but there is an errate that make | ||
198 | * this selection difficult. | ||
199 | * | ||
200 | * In addition, there is no mechanism for communicating with the machine | ||
201 | * driver what the input settings can be. This would need to be implemented | ||
202 | * for stand-alone mode to work. | ||
203 | */ | 190 | */ |
204 | static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, | 191 | static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
205 | int clk_id, unsigned int freq, int dir) | 192 | int clk_id, unsigned int freq, int dir) |
@@ -225,7 +212,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
225 | rates &= ~SNDRV_PCM_RATE_KNOT; | 212 | rates &= ~SNDRV_PCM_RATE_KNOT; |
226 | 213 | ||
227 | if (!rates) { | 214 | if (!rates) { |
228 | printk(KERN_ERR "cs4270: could not find a valid sample rate\n"); | 215 | dev_err(codec->dev, "could not find a valid sample rate\n"); |
229 | return -EINVAL; | 216 | return -EINVAL; |
230 | } | 217 | } |
231 | 218 | ||
@@ -240,8 +227,10 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
240 | return 0; | 227 | return 0; |
241 | } | 228 | } |
242 | 229 | ||
243 | /* | 230 | /** |
244 | * Configure the codec for the selected audio format | 231 | * cs4270_set_dai_fmt - configure the codec for the selected audio format |
232 | * @codec_dai: the codec DAI | ||
233 | * @format: a SND_SOC_DAIFMT_x value indicating the data format | ||
245 | * | 234 | * |
246 | * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the | 235 | * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the |
247 | * codec accordingly. | 236 | * codec accordingly. |
@@ -264,26 +253,23 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
264 | cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK; | 253 | cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK; |
265 | break; | 254 | break; |
266 | default: | 255 | default: |
267 | printk(KERN_ERR "cs4270: invalid DAI format\n"); | 256 | dev_err(codec->dev, "invalid dai format\n"); |
268 | ret = -EINVAL; | 257 | ret = -EINVAL; |
269 | } | 258 | } |
270 | 259 | ||
271 | return ret; | 260 | return ret; |
272 | } | 261 | } |
273 | 262 | ||
274 | /* | 263 | /** |
275 | * A list of addresses on which this CS4270 could use. I2C addresses are | 264 | * cs4270_fill_cache - pre-fill the CS4270 register cache. |
276 | * 7 bits. For the CS4270, the upper four bits are always 1001, and the | 265 | * @codec: the codec for this CS4270 |
277 | * lower three bits are determined via the AD2, AD1, and AD0 pins | 266 | * |
278 | * (respectively). | 267 | * This function fills in the CS4270 register cache by reading the register |
279 | */ | 268 | * values from the hardware. |
280 | static const unsigned short normal_i2c[] = { | 269 | * |
281 | 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, I2C_CLIENT_END | 270 | * This CS4270 registers are cached to avoid excessive I2C I/O operations. |
282 | }; | 271 | * After the initial read to pre-fill the cache, the CS4270 never updates |
283 | I2C_CLIENT_INSMOD; | 272 | * the register values, so we won't have a cache coherency problem. |
284 | |||
285 | /* | ||
286 | * Pre-fill the CS4270 register cache. | ||
287 | * | 273 | * |
288 | * We use the auto-increment feature of the CS4270 to read all registers in | 274 | * We use the auto-increment feature of the CS4270 to read all registers in |
289 | * one shot. | 275 | * one shot. |
@@ -298,7 +284,7 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec) | |||
298 | CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache); | 284 | CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache); |
299 | 285 | ||
300 | if (length != CS4270_NUMREGS) { | 286 | if (length != CS4270_NUMREGS) { |
301 | printk(KERN_ERR "cs4270: I2C read failure, addr=0x%x\n", | 287 | dev_err(codec->dev, "i2c read failure, addr=0x%x\n", |
302 | i2c_client->addr); | 288 | i2c_client->addr); |
303 | return -EIO; | 289 | return -EIO; |
304 | } | 290 | } |
@@ -306,12 +292,17 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec) | |||
306 | return 0; | 292 | return 0; |
307 | } | 293 | } |
308 | 294 | ||
309 | /* | 295 | /** |
310 | * Read from the CS4270 register cache. | 296 | * cs4270_read_reg_cache - read from the CS4270 register cache. |
297 | * @codec: the codec for this CS4270 | ||
298 | * @reg: the register to read | ||
299 | * | ||
300 | * This function returns the value for a given register. It reads only from | ||
301 | * the register cache, not the hardware itself. | ||
311 | * | 302 | * |
312 | * This CS4270 registers are cached to avoid excessive I2C I/O operations. | 303 | * This CS4270 registers are cached to avoid excessive I2C I/O operations. |
313 | * After the initial read to pre-fill the cache, the CS4270 never updates | 304 | * After the initial read to pre-fill the cache, the CS4270 never updates |
314 | * the register values, so we won't have a cache coherncy problem. | 305 | * the register values, so we won't have a cache coherency problem. |
315 | */ | 306 | */ |
316 | static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, | 307 | static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, |
317 | unsigned int reg) | 308 | unsigned int reg) |
@@ -324,8 +315,11 @@ static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, | |||
324 | return cache[reg - CS4270_FIRSTREG]; | 315 | return cache[reg - CS4270_FIRSTREG]; |
325 | } | 316 | } |
326 | 317 | ||
327 | /* | 318 | /** |
328 | * Write to a CS4270 register via the I2C bus. | 319 | * cs4270_i2c_write - write to a CS4270 register via the I2C bus. |
320 | * @codec: the codec for this CS4270 | ||
321 | * @reg: the register to write | ||
322 | * @value: the value to write to the register | ||
329 | * | 323 | * |
330 | * This function writes the given value to the given CS4270 register, and | 324 | * This function writes the given value to the given CS4270 register, and |
331 | * also updates the register cache. | 325 | * also updates the register cache. |
@@ -346,7 +340,7 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg, | |||
346 | if (cache[reg - CS4270_FIRSTREG] != value) { | 340 | if (cache[reg - CS4270_FIRSTREG] != value) { |
347 | struct i2c_client *client = codec->control_data; | 341 | struct i2c_client *client = codec->control_data; |
348 | if (i2c_smbus_write_byte_data(client, reg, value)) { | 342 | if (i2c_smbus_write_byte_data(client, reg, value)) { |
349 | printk(KERN_ERR "cs4270: I2C write failed\n"); | 343 | dev_err(codec->dev, "i2c write failed\n"); |
350 | return -EIO; | 344 | return -EIO; |
351 | } | 345 | } |
352 | 346 | ||
@@ -357,11 +351,17 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg, | |||
357 | return 0; | 351 | return 0; |
358 | } | 352 | } |
359 | 353 | ||
360 | /* | 354 | /** |
361 | * Program the CS4270 with the given hardware parameters. | 355 | * cs4270_hw_params - program the CS4270 with the given hardware parameters. |
356 | * @substream: the audio stream | ||
357 | * @params: the hardware parameters to set | ||
358 | * @dai: the SOC DAI (ignored) | ||
359 | * | ||
360 | * This function programs the hardware with the values provided. | ||
361 | * Specifically, the sample rate and the data format. | ||
362 | * | 362 | * |
363 | * The .ops functions are used to provide board-specific data, like | 363 | * The .ops functions are used to provide board-specific data, like input |
364 | * input frequencies, to this driver. This function takes that information, | 364 | * frequencies, to this driver. This function takes that information, |
365 | * combines it with the hardware parameters provided, and programs the | 365 | * combines it with the hardware parameters provided, and programs the |
366 | * hardware accordingly. | 366 | * hardware accordingly. |
367 | */ | 367 | */ |
@@ -371,7 +371,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
371 | { | 371 | { |
372 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 372 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
373 | struct snd_soc_device *socdev = rtd->socdev; | 373 | struct snd_soc_device *socdev = rtd->socdev; |
374 | struct snd_soc_codec *codec = socdev->codec; | 374 | struct snd_soc_codec *codec = socdev->card->codec; |
375 | struct cs4270_private *cs4270 = codec->private_data; | 375 | struct cs4270_private *cs4270 = codec->private_data; |
376 | int ret; | 376 | int ret; |
377 | unsigned int i; | 377 | unsigned int i; |
@@ -391,7 +391,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
391 | 391 | ||
392 | if (i == NUM_MCLK_RATIOS) { | 392 | if (i == NUM_MCLK_RATIOS) { |
393 | /* We did not find a matching ratio */ | 393 | /* We did not find a matching ratio */ |
394 | printk(KERN_ERR "cs4270: could not find matching ratio\n"); | 394 | dev_err(codec->dev, "could not find matching ratio\n"); |
395 | return -EINVAL; | 395 | return -EINVAL; |
396 | } | 396 | } |
397 | 397 | ||
@@ -401,7 +401,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
401 | CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | | 401 | CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | |
402 | CS4270_PWRCTL_PDN); | 402 | CS4270_PWRCTL_PDN); |
403 | if (ret < 0) { | 403 | if (ret < 0) { |
404 | printk(KERN_ERR "cs4270: I2C write failed\n"); | 404 | dev_err(codec->dev, "i2c write failed\n"); |
405 | return ret; | 405 | return ret; |
406 | } | 406 | } |
407 | 407 | ||
@@ -413,7 +413,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
413 | 413 | ||
414 | ret = snd_soc_write(codec, CS4270_MODE, reg); | 414 | ret = snd_soc_write(codec, CS4270_MODE, reg); |
415 | if (ret < 0) { | 415 | if (ret < 0) { |
416 | printk(KERN_ERR "cs4270: I2C write failed\n"); | 416 | dev_err(codec->dev, "i2c write failed\n"); |
417 | return ret; | 417 | return ret; |
418 | } | 418 | } |
419 | 419 | ||
@@ -430,13 +430,13 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
430 | reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ; | 430 | reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ; |
431 | break; | 431 | break; |
432 | default: | 432 | default: |
433 | printk(KERN_ERR "cs4270: unknown format\n"); | 433 | dev_err(codec->dev, "unknown dai format\n"); |
434 | return -EINVAL; | 434 | return -EINVAL; |
435 | } | 435 | } |
436 | 436 | ||
437 | ret = snd_soc_write(codec, CS4270_FORMAT, reg); | 437 | ret = snd_soc_write(codec, CS4270_FORMAT, reg); |
438 | if (ret < 0) { | 438 | if (ret < 0) { |
439 | printk(KERN_ERR "cs4270: I2C write failed\n"); | 439 | dev_err(codec->dev, "i2c write failed\n"); |
440 | return ret; | 440 | return ret; |
441 | } | 441 | } |
442 | 442 | ||
@@ -447,7 +447,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
447 | reg &= ~CS4270_MUTE_AUTO; | 447 | reg &= ~CS4270_MUTE_AUTO; |
448 | ret = snd_soc_write(codec, CS4270_MUTE, reg); | 448 | ret = snd_soc_write(codec, CS4270_MUTE, reg); |
449 | if (ret < 0) { | 449 | if (ret < 0) { |
450 | printk(KERN_ERR "cs4270: I2C write failed\n"); | 450 | dev_err(codec->dev, "i2c write failed\n"); |
451 | return ret; | 451 | return ret; |
452 | } | 452 | } |
453 | 453 | ||
@@ -460,7 +460,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
460 | reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); | 460 | reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); |
461 | ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); | 461 | ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); |
462 | if (ret < 0) { | 462 | if (ret < 0) { |
463 | printk(KERN_ERR "I2C write failed\n"); | 463 | dev_err(codec->dev, "i2c write failed\n"); |
464 | return ret; | 464 | return ret; |
465 | } | 465 | } |
466 | 466 | ||
@@ -468,7 +468,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
468 | 468 | ||
469 | ret = snd_soc_write(codec, CS4270_PWRCTL, 0); | 469 | ret = snd_soc_write(codec, CS4270_PWRCTL, 0); |
470 | if (ret < 0) { | 470 | if (ret < 0) { |
471 | printk(KERN_ERR "cs4270: I2C write failed\n"); | 471 | dev_err(codec->dev, "i2c write failed\n"); |
472 | return ret; | 472 | return ret; |
473 | } | 473 | } |
474 | 474 | ||
@@ -476,9 +476,10 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
476 | } | 476 | } |
477 | 477 | ||
478 | #ifdef CONFIG_SND_SOC_CS4270_HWMUTE | 478 | #ifdef CONFIG_SND_SOC_CS4270_HWMUTE |
479 | 479 | /** | |
480 | /* | 480 | * cs4270_mute - enable/disable the CS4270 external mute |
481 | * Set the CS4270 external mute | 481 | * @dai: the SOC DAI |
482 | * @mute: 0 = disable mute, 1 = enable mute | ||
482 | * | 483 | * |
483 | * This function toggles the mute bits in the MUTE register. The CS4270's | 484 | * This function toggles the mute bits in the MUTE register. The CS4270's |
484 | * mute capability is intended for external muting circuitry, so if the | 485 | * mute capability is intended for external muting circuitry, so if the |
@@ -501,268 +502,279 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute) | |||
501 | 502 | ||
502 | return snd_soc_write(codec, CS4270_MUTE, reg6); | 503 | return snd_soc_write(codec, CS4270_MUTE, reg6); |
503 | } | 504 | } |
504 | 505 | #else | |
506 | #define cs4270_mute NULL | ||
505 | #endif | 507 | #endif |
506 | 508 | ||
507 | static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *); | ||
508 | |||
509 | /* A list of non-DAPM controls that the CS4270 supports */ | 509 | /* A list of non-DAPM controls that the CS4270 supports */ |
510 | static const struct snd_kcontrol_new cs4270_snd_controls[] = { | 510 | static const struct snd_kcontrol_new cs4270_snd_controls[] = { |
511 | SOC_DOUBLE_R("Master Playback Volume", | 511 | SOC_DOUBLE_R("Master Playback Volume", |
512 | CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) | 512 | CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) |
513 | }; | 513 | }; |
514 | 514 | ||
515 | static const struct i2c_device_id cs4270_id[] = { | ||
516 | {"cs4270", 0}, | ||
517 | {} | ||
518 | }; | ||
519 | MODULE_DEVICE_TABLE(i2c, cs4270_id); | ||
520 | |||
521 | static struct i2c_driver cs4270_i2c_driver = { | ||
522 | .driver = { | ||
523 | .name = "CS4270 I2C", | ||
524 | .owner = THIS_MODULE, | ||
525 | }, | ||
526 | .id_table = cs4270_id, | ||
527 | .probe = cs4270_i2c_probe, | ||
528 | }; | ||
529 | |||
530 | /* | 515 | /* |
531 | * Global variable to store socdev for i2c probe function. | 516 | * cs4270_codec - global variable to store codec for the ASoC probe function |
532 | * | 517 | * |
533 | * If struct i2c_driver had a private_data field, we wouldn't need to use | 518 | * If struct i2c_driver had a private_data field, we wouldn't need to use |
534 | * cs4270_socdec. This is the only way to pass the socdev structure to | 519 | * cs4270_codec. This is the only way to pass the codec structure from |
535 | * cs4270_i2c_probe(). | 520 | * cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good |
536 | * | 521 | * way to synchronize these two functions. cs4270_i2c_probe() can be called |
537 | * The real solution to cs4270_socdev is to create a mechanism | 522 | * multiple times before cs4270_probe() is called even once. So for now, we |
538 | * that maps I2C addresses to snd_soc_device structures. Perhaps the | 523 | * also only allow cs4270_i2c_probe() to be run once. That means that we do |
539 | * creation of the snd_soc_device object should be moved out of | 524 | * not support more than one cs4270 device in the system, at least for now. |
540 | * cs4270_probe() and into cs4270_i2c_probe(), but that would make this | ||
541 | * driver dependent on I2C. The CS4270 supports "stand-alone" mode, whereby | ||
542 | * the chip is *not* connected to the I2C bus, but is instead configured via | ||
543 | * input pins. | ||
544 | */ | 525 | */ |
545 | static struct snd_soc_device *cs4270_socdev; | 526 | static struct snd_soc_codec *cs4270_codec; |
546 | 527 | ||
547 | /* | 528 | struct snd_soc_dai cs4270_dai = { |
548 | * Initialize the I2C interface of the CS4270 | 529 | .name = "cs4270", |
549 | * | 530 | .playback = { |
550 | * This function is called for whenever the I2C subsystem finds a device | 531 | .stream_name = "Playback", |
551 | * at a particular address. | 532 | .channels_min = 1, |
533 | .channels_max = 2, | ||
534 | .rates = 0, | ||
535 | .formats = CS4270_FORMATS, | ||
536 | }, | ||
537 | .capture = { | ||
538 | .stream_name = "Capture", | ||
539 | .channels_min = 1, | ||
540 | .channels_max = 2, | ||
541 | .rates = 0, | ||
542 | .formats = CS4270_FORMATS, | ||
543 | }, | ||
544 | .ops = { | ||
545 | .hw_params = cs4270_hw_params, | ||
546 | .set_sysclk = cs4270_set_dai_sysclk, | ||
547 | .set_fmt = cs4270_set_dai_fmt, | ||
548 | .digital_mute = cs4270_mute, | ||
549 | }, | ||
550 | }; | ||
551 | EXPORT_SYMBOL_GPL(cs4270_dai); | ||
552 | |||
553 | /** | ||
554 | * cs4270_probe - ASoC probe function | ||
555 | * @pdev: platform device | ||
552 | * | 556 | * |
553 | * Note: snd_soc_new_pcms() must be called before this function can be called, | 557 | * This function is called when ASoC has all the pieces it needs to |
554 | * because of snd_ctl_add(). | 558 | * instantiate a sound driver. |
555 | */ | 559 | */ |
556 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, | 560 | static int cs4270_probe(struct platform_device *pdev) |
557 | const struct i2c_device_id *id) | ||
558 | { | 561 | { |
559 | struct snd_soc_device *socdev = cs4270_socdev; | 562 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
560 | struct snd_soc_codec *codec = socdev->codec; | 563 | struct snd_soc_codec *codec = cs4270_codec; |
561 | int i; | 564 | unsigned int i; |
562 | int ret = 0; | 565 | int ret; |
563 | |||
564 | /* Probing all possible addresses has one drawback: if there are | ||
565 | multiple CS4270s on the bus, then you cannot specify which | ||
566 | socdev is matched with which CS4270. For now, we just reject | ||
567 | this I2C device if the socdev already has one attached. */ | ||
568 | if (codec->control_data) | ||
569 | return -ENODEV; | ||
570 | |||
571 | /* Note: codec_dai->codec is NULL here */ | ||
572 | |||
573 | codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL); | ||
574 | if (!codec->reg_cache) { | ||
575 | printk(KERN_ERR "cs4270: could not allocate register cache\n"); | ||
576 | ret = -ENOMEM; | ||
577 | goto error; | ||
578 | } | ||
579 | |||
580 | /* Verify that we have a CS4270 */ | ||
581 | |||
582 | ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); | ||
583 | if (ret < 0) { | ||
584 | printk(KERN_ERR "cs4270: failed to read I2C\n"); | ||
585 | goto error; | ||
586 | } | ||
587 | /* The top four bits of the chip ID should be 1100. */ | ||
588 | if ((ret & 0xF0) != 0xC0) { | ||
589 | /* The device at this address is not a CS4270 codec */ | ||
590 | ret = -ENODEV; | ||
591 | goto error; | ||
592 | } | ||
593 | |||
594 | printk(KERN_INFO "cs4270: found device at I2C address %X\n", | ||
595 | i2c_client->addr); | ||
596 | printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF); | ||
597 | |||
598 | codec->control_data = i2c_client; | ||
599 | codec->read = cs4270_read_reg_cache; | ||
600 | codec->write = cs4270_i2c_write; | ||
601 | codec->reg_cache_size = CS4270_NUMREGS; | ||
602 | 566 | ||
603 | /* The I2C interface is set up, so pre-fill our register cache */ | 567 | /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ |
568 | socdev->card->codec = codec; | ||
604 | 569 | ||
605 | ret = cs4270_fill_cache(codec); | 570 | /* Register PCMs */ |
571 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
606 | if (ret < 0) { | 572 | if (ret < 0) { |
607 | printk(KERN_ERR "cs4270: failed to fill register cache\n"); | 573 | dev_err(codec->dev, "failed to create pcms\n"); |
608 | goto error; | 574 | return ret; |
609 | } | 575 | } |
610 | 576 | ||
611 | /* Add the non-DAPM controls */ | 577 | /* Add the non-DAPM controls */ |
612 | |||
613 | for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) { | 578 | for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) { |
614 | struct snd_kcontrol *kctrl = | 579 | struct snd_kcontrol *kctrl; |
615 | snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL); | 580 | |
581 | kctrl = snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL); | ||
582 | if (!kctrl) { | ||
583 | dev_err(codec->dev, "error creating control '%s'\n", | ||
584 | cs4270_snd_controls[i].name); | ||
585 | ret = -ENOMEM; | ||
586 | goto error_free_pcms; | ||
587 | } | ||
616 | 588 | ||
617 | ret = snd_ctl_add(codec->card, kctrl); | 589 | ret = snd_ctl_add(codec->card, kctrl); |
618 | if (ret < 0) | 590 | if (ret < 0) { |
619 | goto error; | 591 | dev_err(codec->dev, "error adding control '%s'\n", |
592 | cs4270_snd_controls[i].name); | ||
593 | goto error_free_pcms; | ||
594 | } | ||
620 | } | 595 | } |
621 | 596 | ||
622 | i2c_set_clientdata(i2c_client, codec); | 597 | /* And finally, register the socdev */ |
598 | ret = snd_soc_init_card(socdev); | ||
599 | if (ret < 0) { | ||
600 | dev_err(codec->dev, "failed to register card\n"); | ||
601 | goto error_free_pcms; | ||
602 | } | ||
623 | 603 | ||
624 | return 0; | 604 | return 0; |
625 | 605 | ||
626 | error: | 606 | error_free_pcms: |
627 | codec->control_data = NULL; | 607 | snd_soc_free_pcms(socdev); |
628 | |||
629 | kfree(codec->reg_cache); | ||
630 | codec->reg_cache = NULL; | ||
631 | codec->reg_cache_size = 0; | ||
632 | 608 | ||
633 | return ret; | 609 | return ret; |
634 | } | 610 | } |
635 | 611 | ||
636 | #endif /* USE_I2C*/ | 612 | /** |
613 | * cs4270_remove - ASoC remove function | ||
614 | * @pdev: platform device | ||
615 | * | ||
616 | * This function is the counterpart to cs4270_probe(). | ||
617 | */ | ||
618 | static int cs4270_remove(struct platform_device *pdev) | ||
619 | { | ||
620 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
637 | 621 | ||
638 | struct snd_soc_dai cs4270_dai = { | 622 | snd_soc_free_pcms(socdev); |
639 | .name = "CS4270", | 623 | |
640 | .playback = { | 624 | return 0; |
641 | .stream_name = "Playback", | ||
642 | .channels_min = 1, | ||
643 | .channels_max = 2, | ||
644 | .rates = 0, | ||
645 | .formats = CS4270_FORMATS, | ||
646 | }, | ||
647 | .capture = { | ||
648 | .stream_name = "Capture", | ||
649 | .channels_min = 1, | ||
650 | .channels_max = 2, | ||
651 | .rates = 0, | ||
652 | .formats = CS4270_FORMATS, | ||
653 | }, | ||
654 | }; | 625 | }; |
655 | EXPORT_SYMBOL_GPL(cs4270_dai); | ||
656 | 626 | ||
657 | /* | 627 | /** |
658 | * ASoC probe function | 628 | * cs4270_i2c_probe - initialize the I2C interface of the CS4270 |
629 | * @i2c_client: the I2C client object | ||
630 | * @id: the I2C device ID (ignored) | ||
659 | * | 631 | * |
660 | * This function is called when the machine driver calls | 632 | * This function is called whenever the I2C subsystem finds a device that |
661 | * platform_device_add(). | 633 | * matches the device ID given via a prior call to i2c_add_driver(). |
662 | */ | 634 | */ |
663 | static int cs4270_probe(struct platform_device *pdev) | 635 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, |
636 | const struct i2c_device_id *id) | ||
664 | { | 637 | { |
665 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
666 | struct snd_soc_codec *codec; | 638 | struct snd_soc_codec *codec; |
667 | int ret = 0; | 639 | struct cs4270_private *cs4270; |
640 | int ret; | ||
641 | |||
642 | /* For now, we only support one cs4270 device in the system. See the | ||
643 | * comment for cs4270_codec. | ||
644 | */ | ||
645 | if (cs4270_codec) { | ||
646 | dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n", | ||
647 | i2c_client->addr); | ||
648 | dev_err(&i2c_client->dev, "only one per board allowed\n"); | ||
649 | /* Should we return something other than ENODEV here? */ | ||
650 | return -ENODEV; | ||
651 | } | ||
652 | |||
653 | /* Verify that we have a CS4270 */ | ||
654 | |||
655 | ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); | ||
656 | if (ret < 0) { | ||
657 | dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n", | ||
658 | i2c_client->addr); | ||
659 | return ret; | ||
660 | } | ||
661 | /* The top four bits of the chip ID should be 1100. */ | ||
662 | if ((ret & 0xF0) != 0xC0) { | ||
663 | dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n", | ||
664 | i2c_client->addr); | ||
665 | return -ENODEV; | ||
666 | } | ||
668 | 667 | ||
669 | printk(KERN_INFO "CS4270 ALSA SoC Codec\n"); | 668 | dev_info(&i2c_client->dev, "found device at i2c address %X\n", |
669 | i2c_client->addr); | ||
670 | dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF); | ||
670 | 671 | ||
671 | /* Allocate enough space for the snd_soc_codec structure | 672 | /* Allocate enough space for the snd_soc_codec structure |
672 | and our private data together. */ | 673 | and our private data together. */ |
673 | codec = kzalloc(ALIGN(sizeof(struct snd_soc_codec), 4) + | 674 | cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL); |
674 | sizeof(struct cs4270_private), GFP_KERNEL); | 675 | if (!cs4270) { |
675 | if (!codec) { | 676 | dev_err(&i2c_client->dev, "could not allocate codec\n"); |
676 | printk(KERN_ERR "cs4270: Could not allocate codec structure\n"); | ||
677 | return -ENOMEM; | 677 | return -ENOMEM; |
678 | } | 678 | } |
679 | codec = &cs4270->codec; | ||
679 | 680 | ||
680 | mutex_init(&codec->mutex); | 681 | mutex_init(&codec->mutex); |
681 | INIT_LIST_HEAD(&codec->dapm_widgets); | 682 | INIT_LIST_HEAD(&codec->dapm_widgets); |
682 | INIT_LIST_HEAD(&codec->dapm_paths); | 683 | INIT_LIST_HEAD(&codec->dapm_paths); |
683 | 684 | ||
685 | codec->dev = &i2c_client->dev; | ||
684 | codec->name = "CS4270"; | 686 | codec->name = "CS4270"; |
685 | codec->owner = THIS_MODULE; | 687 | codec->owner = THIS_MODULE; |
686 | codec->dai = &cs4270_dai; | 688 | codec->dai = &cs4270_dai; |
687 | codec->num_dai = 1; | 689 | codec->num_dai = 1; |
688 | codec->private_data = (void *) codec + | 690 | codec->private_data = cs4270; |
689 | ALIGN(sizeof(struct snd_soc_codec), 4); | 691 | codec->control_data = i2c_client; |
690 | 692 | codec->read = cs4270_read_reg_cache; | |
691 | socdev->codec = codec; | 693 | codec->write = cs4270_i2c_write; |
694 | codec->reg_cache = cs4270->reg_cache; | ||
695 | codec->reg_cache_size = CS4270_NUMREGS; | ||
692 | 696 | ||
693 | /* Register PCMs */ | 697 | /* The I2C interface is set up, so pre-fill our register cache */ |
694 | 698 | ||
695 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 699 | ret = cs4270_fill_cache(codec); |
696 | if (ret < 0) { | 700 | if (ret < 0) { |
697 | printk(KERN_ERR "cs4270: failed to create PCMs\n"); | 701 | dev_err(&i2c_client->dev, "failed to fill register cache\n"); |
698 | goto error_free_codec; | 702 | goto error_free_codec; |
699 | } | 703 | } |
700 | 704 | ||
701 | #ifdef USE_I2C | 705 | /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI |
702 | cs4270_socdev = socdev; | 706 | * structure for each CS4270 device, but the machine driver needs to |
703 | 707 | * have a pointer to the DAI structure, so for now it must be a global | |
704 | ret = i2c_add_driver(&cs4270_i2c_driver); | 708 | * variable. |
705 | if (ret) { | 709 | */ |
706 | printk(KERN_ERR "cs4270: failed to attach driver"); | 710 | cs4270_dai.dev = &i2c_client->dev; |
707 | goto error_free_pcms; | ||
708 | } | ||
709 | |||
710 | /* Did we find a CS4270 on the I2C bus? */ | ||
711 | if (codec->control_data) { | ||
712 | /* Initialize codec ops */ | ||
713 | cs4270_dai.ops.hw_params = cs4270_hw_params; | ||
714 | cs4270_dai.ops.set_sysclk = cs4270_set_dai_sysclk; | ||
715 | cs4270_dai.ops.set_fmt = cs4270_set_dai_fmt; | ||
716 | #ifdef CONFIG_SND_SOC_CS4270_HWMUTE | ||
717 | cs4270_dai.ops.digital_mute = cs4270_mute; | ||
718 | #endif | ||
719 | } else | ||
720 | printk(KERN_INFO "cs4270: no I2C device found, " | ||
721 | "using stand-alone mode\n"); | ||
722 | #else | ||
723 | printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n"); | ||
724 | #endif | ||
725 | 711 | ||
726 | ret = snd_soc_init_card(socdev); | 712 | /* Register the DAI. If all the other ASoC driver have already |
713 | * registered, then this will call our probe function, so | ||
714 | * cs4270_codec needs to be ready. | ||
715 | */ | ||
716 | cs4270_codec = codec; | ||
717 | ret = snd_soc_register_dai(&cs4270_dai); | ||
727 | if (ret < 0) { | 718 | if (ret < 0) { |
728 | printk(KERN_ERR "cs4270: failed to register card\n"); | 719 | dev_err(&i2c_client->dev, "failed to register DAIe\n"); |
729 | goto error_del_driver; | 720 | goto error_free_codec; |
730 | } | 721 | } |
731 | 722 | ||
732 | return 0; | 723 | i2c_set_clientdata(i2c_client, cs4270); |
733 | |||
734 | error_del_driver: | ||
735 | #ifdef USE_I2C | ||
736 | i2c_del_driver(&cs4270_i2c_driver); | ||
737 | 724 | ||
738 | error_free_pcms: | 725 | return 0; |
739 | #endif | ||
740 | snd_soc_free_pcms(socdev); | ||
741 | 726 | ||
742 | error_free_codec: | 727 | error_free_codec: |
743 | kfree(socdev->codec); | 728 | kfree(cs4270); |
744 | socdev->codec = NULL; | 729 | cs4270_codec = NULL; |
730 | cs4270_dai.dev = NULL; | ||
745 | 731 | ||
746 | return ret; | 732 | return ret; |
747 | } | 733 | } |
748 | 734 | ||
749 | static int cs4270_remove(struct platform_device *pdev) | 735 | /** |
736 | * cs4270_i2c_remove - remove an I2C device | ||
737 | * @i2c_client: the I2C client object | ||
738 | * | ||
739 | * This function is the counterpart to cs4270_i2c_probe(). | ||
740 | */ | ||
741 | static int cs4270_i2c_remove(struct i2c_client *i2c_client) | ||
750 | { | 742 | { |
751 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 743 | struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client); |
752 | |||
753 | snd_soc_free_pcms(socdev); | ||
754 | |||
755 | #ifdef USE_I2C | ||
756 | i2c_del_driver(&cs4270_i2c_driver); | ||
757 | #endif | ||
758 | 744 | ||
759 | kfree(socdev->codec); | 745 | kfree(cs4270); |
760 | socdev->codec = NULL; | 746 | cs4270_codec = NULL; |
747 | cs4270_dai.dev = NULL; | ||
761 | 748 | ||
762 | return 0; | 749 | return 0; |
763 | } | 750 | } |
764 | 751 | ||
765 | /* | 752 | /* |
753 | * cs4270_id - I2C device IDs supported by this driver | ||
754 | */ | ||
755 | static struct i2c_device_id cs4270_id[] = { | ||
756 | {"cs4270", 0}, | ||
757 | {} | ||
758 | }; | ||
759 | MODULE_DEVICE_TABLE(i2c, cs4270_id); | ||
760 | |||
761 | /* | ||
762 | * cs4270_i2c_driver - I2C device identification | ||
763 | * | ||
764 | * This structure tells the I2C subsystem how to identify and support a | ||
765 | * given I2C device type. | ||
766 | */ | ||
767 | static struct i2c_driver cs4270_i2c_driver = { | ||
768 | .driver = { | ||
769 | .name = "cs4270", | ||
770 | .owner = THIS_MODULE, | ||
771 | }, | ||
772 | .id_table = cs4270_id, | ||
773 | .probe = cs4270_i2c_probe, | ||
774 | .remove = cs4270_i2c_remove, | ||
775 | }; | ||
776 | |||
777 | /* | ||
766 | * ASoC codec device structure | 778 | * ASoC codec device structure |
767 | * | 779 | * |
768 | * Assign this variable to the codec_dev field of the machine driver's | 780 | * Assign this variable to the codec_dev field of the machine driver's |
@@ -776,13 +788,15 @@ EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); | |||
776 | 788 | ||
777 | static int __init cs4270_init(void) | 789 | static int __init cs4270_init(void) |
778 | { | 790 | { |
779 | return snd_soc_register_dai(&cs4270_dai); | 791 | pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n"); |
792 | |||
793 | return i2c_add_driver(&cs4270_i2c_driver); | ||
780 | } | 794 | } |
781 | module_init(cs4270_init); | 795 | module_init(cs4270_init); |
782 | 796 | ||
783 | static void __exit cs4270_exit(void) | 797 | static void __exit cs4270_exit(void) |
784 | { | 798 | { |
785 | snd_soc_unregister_dai(&cs4270_dai); | 799 | i2c_del_driver(&cs4270_i2c_driver); |
786 | } | 800 | } |
787 | module_exit(cs4270_exit); | 801 | module_exit(cs4270_exit); |
788 | 802 | ||
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 9a3e67e5319c..5cda9e6b5a74 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c | |||
@@ -67,11 +67,11 @@ static int pcm3008_soc_probe(struct platform_device *pdev) | |||
67 | 67 | ||
68 | printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION); | 68 | printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION); |
69 | 69 | ||
70 | socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 70 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); |
71 | if (!socdev->codec) | 71 | if (!socdev->card->codec) |
72 | return -ENOMEM; | 72 | return -ENOMEM; |
73 | 73 | ||
74 | codec = socdev->codec; | 74 | codec = socdev->card->codec; |
75 | mutex_init(&codec->mutex); | 75 | mutex_init(&codec->mutex); |
76 | 76 | ||
77 | codec->name = "PCM3008"; | 77 | codec->name = "PCM3008"; |
@@ -139,7 +139,7 @@ gpio_err: | |||
139 | card_err: | 139 | card_err: |
140 | snd_soc_free_pcms(socdev); | 140 | snd_soc_free_pcms(socdev); |
141 | pcm_err: | 141 | pcm_err: |
142 | kfree(socdev->codec); | 142 | kfree(socdev->card->codec); |
143 | 143 | ||
144 | return ret; | 144 | return ret; |
145 | } | 145 | } |
@@ -147,7 +147,7 @@ pcm_err: | |||
147 | static int pcm3008_soc_remove(struct platform_device *pdev) | 147 | static int pcm3008_soc_remove(struct platform_device *pdev) |
148 | { | 148 | { |
149 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 149 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
150 | struct snd_soc_codec *codec = socdev->codec; | 150 | struct snd_soc_codec *codec = socdev->card->codec; |
151 | struct pcm3008_setup_data *setup = socdev->codec_data; | 151 | struct pcm3008_setup_data *setup = socdev->codec_data; |
152 | 152 | ||
153 | if (!codec) | 153 | if (!codec) |
@@ -155,7 +155,7 @@ static int pcm3008_soc_remove(struct platform_device *pdev) | |||
155 | 155 | ||
156 | pcm3008_gpio_free(setup); | 156 | pcm3008_gpio_free(setup); |
157 | snd_soc_free_pcms(socdev); | 157 | snd_soc_free_pcms(socdev); |
158 | kfree(socdev->codec); | 158 | kfree(socdev->card->codec); |
159 | 159 | ||
160 | return 0; | 160 | return 0; |
161 | } | 161 | } |
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index cac373616768..58e225dadc7e 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c | |||
@@ -151,21 +151,6 @@ SOC_ENUM("Capture Source", ssm2602_enum[0]), | |||
151 | SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]), | 151 | SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]), |
152 | }; | 152 | }; |
153 | 153 | ||
154 | /* add non dapm controls */ | ||
155 | static int ssm2602_add_controls(struct snd_soc_codec *codec) | ||
156 | { | ||
157 | int err, i; | ||
158 | |||
159 | for (i = 0; i < ARRAY_SIZE(ssm2602_snd_controls); i++) { | ||
160 | err = snd_ctl_add(codec->card, | ||
161 | snd_soc_cnew(&ssm2602_snd_controls[i], codec, NULL)); | ||
162 | if (err < 0) | ||
163 | return err; | ||
164 | } | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | /* Output Mixer */ | 154 | /* Output Mixer */ |
170 | static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = { | 155 | static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = { |
171 | SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0), | 156 | SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0), |
@@ -291,7 +276,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream, | |||
291 | u16 srate; | 276 | u16 srate; |
292 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 277 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
293 | struct snd_soc_device *socdev = rtd->socdev; | 278 | struct snd_soc_device *socdev = rtd->socdev; |
294 | struct snd_soc_codec *codec = socdev->codec; | 279 | struct snd_soc_codec *codec = socdev->card->codec; |
295 | struct ssm2602_priv *ssm2602 = codec->private_data; | 280 | struct ssm2602_priv *ssm2602 = codec->private_data; |
296 | struct i2c_client *i2c = codec->control_data; | 281 | struct i2c_client *i2c = codec->control_data; |
297 | u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; | 282 | u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; |
@@ -336,7 +321,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream, | |||
336 | { | 321 | { |
337 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 322 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
338 | struct snd_soc_device *socdev = rtd->socdev; | 323 | struct snd_soc_device *socdev = rtd->socdev; |
339 | struct snd_soc_codec *codec = socdev->codec; | 324 | struct snd_soc_codec *codec = socdev->card->codec; |
340 | struct ssm2602_priv *ssm2602 = codec->private_data; | 325 | struct ssm2602_priv *ssm2602 = codec->private_data; |
341 | struct i2c_client *i2c = codec->control_data; | 326 | struct i2c_client *i2c = codec->control_data; |
342 | struct snd_pcm_runtime *master_runtime; | 327 | struct snd_pcm_runtime *master_runtime; |
@@ -373,7 +358,7 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream, | |||
373 | { | 358 | { |
374 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 359 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
375 | struct snd_soc_device *socdev = rtd->socdev; | 360 | struct snd_soc_device *socdev = rtd->socdev; |
376 | struct snd_soc_codec *codec = socdev->codec; | 361 | struct snd_soc_codec *codec = socdev->card->codec; |
377 | /* set active */ | 362 | /* set active */ |
378 | ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); | 363 | ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); |
379 | 364 | ||
@@ -385,7 +370,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream, | |||
385 | { | 370 | { |
386 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 371 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
387 | struct snd_soc_device *socdev = rtd->socdev; | 372 | struct snd_soc_device *socdev = rtd->socdev; |
388 | struct snd_soc_codec *codec = socdev->codec; | 373 | struct snd_soc_codec *codec = socdev->card->codec; |
389 | struct ssm2602_priv *ssm2602 = codec->private_data; | 374 | struct ssm2602_priv *ssm2602 = codec->private_data; |
390 | /* deactivate */ | 375 | /* deactivate */ |
391 | if (!codec->active) | 376 | if (!codec->active) |
@@ -550,7 +535,7 @@ EXPORT_SYMBOL_GPL(ssm2602_dai); | |||
550 | static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state) | 535 | static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state) |
551 | { | 536 | { |
552 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 537 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
553 | struct snd_soc_codec *codec = socdev->codec; | 538 | struct snd_soc_codec *codec = socdev->card->codec; |
554 | 539 | ||
555 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); | 540 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); |
556 | return 0; | 541 | return 0; |
@@ -559,7 +544,7 @@ static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state) | |||
559 | static int ssm2602_resume(struct platform_device *pdev) | 544 | static int ssm2602_resume(struct platform_device *pdev) |
560 | { | 545 | { |
561 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 546 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
562 | struct snd_soc_codec *codec = socdev->codec; | 547 | struct snd_soc_codec *codec = socdev->card->codec; |
563 | int i; | 548 | int i; |
564 | u8 data[2]; | 549 | u8 data[2]; |
565 | u16 *cache = codec->reg_cache; | 550 | u16 *cache = codec->reg_cache; |
@@ -581,7 +566,7 @@ static int ssm2602_resume(struct platform_device *pdev) | |||
581 | */ | 566 | */ |
582 | static int ssm2602_init(struct snd_soc_device *socdev) | 567 | static int ssm2602_init(struct snd_soc_device *socdev) |
583 | { | 568 | { |
584 | struct snd_soc_codec *codec = socdev->codec; | 569 | struct snd_soc_codec *codec = socdev->card->codec; |
585 | int reg, ret = 0; | 570 | int reg, ret = 0; |
586 | 571 | ||
587 | codec->name = "SSM2602"; | 572 | codec->name = "SSM2602"; |
@@ -622,7 +607,8 @@ static int ssm2602_init(struct snd_soc_device *socdev) | |||
622 | APANA_ENABLE_MIC_BOOST); | 607 | APANA_ENABLE_MIC_BOOST); |
623 | ssm2602_write(codec, SSM2602_PWR, 0); | 608 | ssm2602_write(codec, SSM2602_PWR, 0); |
624 | 609 | ||
625 | ssm2602_add_controls(codec); | 610 | snd_soc_add_controls(codec, ssm2602_snd_controls, |
611 | ARRAY_SIZE(ssm2602_snd_controls)); | ||
626 | ssm2602_add_widgets(codec); | 612 | ssm2602_add_widgets(codec); |
627 | ret = snd_soc_init_card(socdev); | 613 | ret = snd_soc_init_card(socdev); |
628 | if (ret < 0) { | 614 | if (ret < 0) { |
@@ -653,7 +639,7 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c, | |||
653 | const struct i2c_device_id *id) | 639 | const struct i2c_device_id *id) |
654 | { | 640 | { |
655 | struct snd_soc_device *socdev = ssm2602_socdev; | 641 | struct snd_soc_device *socdev = ssm2602_socdev; |
656 | struct snd_soc_codec *codec = socdev->codec; | 642 | struct snd_soc_codec *codec = socdev->card->codec; |
657 | int ret; | 643 | int ret; |
658 | 644 | ||
659 | i2c_set_clientdata(i2c, codec); | 645 | i2c_set_clientdata(i2c, codec); |
@@ -747,7 +733,7 @@ static int ssm2602_probe(struct platform_device *pdev) | |||
747 | } | 733 | } |
748 | 734 | ||
749 | codec->private_data = ssm2602; | 735 | codec->private_data = ssm2602; |
750 | socdev->codec = codec; | 736 | socdev->card->codec = codec; |
751 | mutex_init(&codec->mutex); | 737 | mutex_init(&codec->mutex); |
752 | INIT_LIST_HEAD(&codec->dapm_widgets); | 738 | INIT_LIST_HEAD(&codec->dapm_widgets); |
753 | INIT_LIST_HEAD(&codec->dapm_paths); | 739 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -768,7 +754,7 @@ static int ssm2602_probe(struct platform_device *pdev) | |||
768 | static int ssm2602_remove(struct platform_device *pdev) | 754 | static int ssm2602_remove(struct platform_device *pdev) |
769 | { | 755 | { |
770 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 756 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
771 | struct snd_soc_codec *codec = socdev->codec; | 757 | struct snd_soc_codec *codec = socdev->card->codec; |
772 | 758 | ||
773 | if (codec->control_data) | 759 | if (codec->control_data) |
774 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); | 760 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index cfdea007c4cb..8b20c360adf5 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -183,24 +183,6 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { | |||
183 | SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), | 183 | SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), |
184 | }; | 184 | }; |
185 | 185 | ||
186 | /* add non dapm controls */ | ||
187 | static int tlv320aic23_add_controls(struct snd_soc_codec *codec) | ||
188 | { | ||
189 | |||
190 | int err, i; | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) { | ||
193 | err = snd_ctl_add(codec->card, | ||
194 | snd_soc_cnew(&tlv320aic23_snd_controls[i], | ||
195 | codec, NULL)); | ||
196 | if (err < 0) | ||
197 | return err; | ||
198 | } | ||
199 | |||
200 | return 0; | ||
201 | |||
202 | } | ||
203 | |||
204 | /* PGA Mixer controls for Line and Mic switch */ | 186 | /* PGA Mixer controls for Line and Mic switch */ |
205 | static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = { | 187 | static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = { |
206 | SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0), | 188 | SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0), |
@@ -423,7 +405,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, | |||
423 | { | 405 | { |
424 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 406 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
425 | struct snd_soc_device *socdev = rtd->socdev; | 407 | struct snd_soc_device *socdev = rtd->socdev; |
426 | struct snd_soc_codec *codec = socdev->codec; | 408 | struct snd_soc_codec *codec = socdev->card->codec; |
427 | u16 iface_reg; | 409 | u16 iface_reg; |
428 | int ret; | 410 | int ret; |
429 | struct aic23 *aic23 = container_of(codec, struct aic23, codec); | 411 | struct aic23 *aic23 = container_of(codec, struct aic23, codec); |
@@ -471,7 +453,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream, | |||
471 | { | 453 | { |
472 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 454 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
473 | struct snd_soc_device *socdev = rtd->socdev; | 455 | struct snd_soc_device *socdev = rtd->socdev; |
474 | struct snd_soc_codec *codec = socdev->codec; | 456 | struct snd_soc_codec *codec = socdev->card->codec; |
475 | 457 | ||
476 | /* set active */ | 458 | /* set active */ |
477 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); | 459 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); |
@@ -484,7 +466,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, | |||
484 | { | 466 | { |
485 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 467 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
486 | struct snd_soc_device *socdev = rtd->socdev; | 468 | struct snd_soc_device *socdev = rtd->socdev; |
487 | struct snd_soc_codec *codec = socdev->codec; | 469 | struct snd_soc_codec *codec = socdev->card->codec; |
488 | struct aic23 *aic23 = container_of(codec, struct aic23, codec); | 470 | struct aic23 *aic23 = container_of(codec, struct aic23, codec); |
489 | 471 | ||
490 | /* deactivate */ | 472 | /* deactivate */ |
@@ -627,7 +609,7 @@ static int tlv320aic23_suspend(struct platform_device *pdev, | |||
627 | pm_message_t state) | 609 | pm_message_t state) |
628 | { | 610 | { |
629 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 611 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
630 | struct snd_soc_codec *codec = socdev->codec; | 612 | struct snd_soc_codec *codec = socdev->card->codec; |
631 | 613 | ||
632 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); | 614 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); |
633 | tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); | 615 | tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); |
@@ -638,7 +620,7 @@ static int tlv320aic23_suspend(struct platform_device *pdev, | |||
638 | static int tlv320aic23_resume(struct platform_device *pdev) | 620 | static int tlv320aic23_resume(struct platform_device *pdev) |
639 | { | 621 | { |
640 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 622 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
641 | struct snd_soc_codec *codec = socdev->codec; | 623 | struct snd_soc_codec *codec = socdev->card->codec; |
642 | int i; | 624 | int i; |
643 | u16 reg; | 625 | u16 reg; |
644 | 626 | ||
@@ -660,7 +642,7 @@ static int tlv320aic23_resume(struct platform_device *pdev) | |||
660 | */ | 642 | */ |
661 | static int tlv320aic23_init(struct snd_soc_device *socdev) | 643 | static int tlv320aic23_init(struct snd_soc_device *socdev) |
662 | { | 644 | { |
663 | struct snd_soc_codec *codec = socdev->codec; | 645 | struct snd_soc_codec *codec = socdev->card->codec; |
664 | int ret = 0; | 646 | int ret = 0; |
665 | u16 reg; | 647 | u16 reg; |
666 | 648 | ||
@@ -718,7 +700,8 @@ static int tlv320aic23_init(struct snd_soc_device *socdev) | |||
718 | 700 | ||
719 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); | 701 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); |
720 | 702 | ||
721 | tlv320aic23_add_controls(codec); | 703 | snd_soc_add_controls(codec, tlv320aic23_snd_controls, |
704 | ARRAY_SIZE(tlv320aic23_snd_controls)); | ||
722 | tlv320aic23_add_widgets(codec); | 705 | tlv320aic23_add_widgets(codec); |
723 | ret = snd_soc_init_card(socdev); | 706 | ret = snd_soc_init_card(socdev); |
724 | if (ret < 0) { | 707 | if (ret < 0) { |
@@ -746,7 +729,7 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c, | |||
746 | const struct i2c_device_id *i2c_id) | 729 | const struct i2c_device_id *i2c_id) |
747 | { | 730 | { |
748 | struct snd_soc_device *socdev = tlv320aic23_socdev; | 731 | struct snd_soc_device *socdev = tlv320aic23_socdev; |
749 | struct snd_soc_codec *codec = socdev->codec; | 732 | struct snd_soc_codec *codec = socdev->card->codec; |
750 | int ret; | 733 | int ret; |
751 | 734 | ||
752 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 735 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
@@ -804,7 +787,7 @@ static int tlv320aic23_probe(struct platform_device *pdev) | |||
804 | if (aic23 == NULL) | 787 | if (aic23 == NULL) |
805 | return -ENOMEM; | 788 | return -ENOMEM; |
806 | codec = &aic23->codec; | 789 | codec = &aic23->codec; |
807 | socdev->codec = codec; | 790 | socdev->card->codec = codec; |
808 | mutex_init(&codec->mutex); | 791 | mutex_init(&codec->mutex); |
809 | INIT_LIST_HEAD(&codec->dapm_widgets); | 792 | INIT_LIST_HEAD(&codec->dapm_widgets); |
810 | INIT_LIST_HEAD(&codec->dapm_paths); | 793 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -823,7 +806,7 @@ static int tlv320aic23_probe(struct platform_device *pdev) | |||
823 | static int tlv320aic23_remove(struct platform_device *pdev) | 806 | static int tlv320aic23_remove(struct platform_device *pdev) |
824 | { | 807 | { |
825 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 808 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
826 | struct snd_soc_codec *codec = socdev->codec; | 809 | struct snd_soc_codec *codec = socdev->card->codec; |
827 | struct aic23 *aic23 = container_of(codec, struct aic23, codec); | 810 | struct aic23 *aic23 = container_of(codec, struct aic23, codec); |
828 | 811 | ||
829 | if (codec->control_data) | 812 | if (codec->control_data) |
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 29f2f1a017fd..229e464cf713 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c | |||
@@ -130,7 +130,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream, | |||
130 | { | 130 | { |
131 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 131 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
132 | struct snd_soc_device *socdev = rtd->socdev; | 132 | struct snd_soc_device *socdev = rtd->socdev; |
133 | struct snd_soc_codec *codec = socdev->codec; | 133 | struct snd_soc_codec *codec = socdev->card->codec; |
134 | struct aic26 *aic26 = codec->private_data; | 134 | struct aic26 *aic26 = codec->private_data; |
135 | int fsref, divisor, wlen, pval, jval, dval, qval; | 135 | int fsref, divisor, wlen, pval, jval, dval, qval; |
136 | u16 reg; | 136 | u16 reg; |
@@ -338,7 +338,7 @@ static int aic26_probe(struct platform_device *pdev) | |||
338 | return -ENODEV; | 338 | return -ENODEV; |
339 | } | 339 | } |
340 | codec = &aic26->codec; | 340 | codec = &aic26->codec; |
341 | socdev->codec = codec; | 341 | socdev->card->codec = codec; |
342 | 342 | ||
343 | dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n", | 343 | dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n", |
344 | &pdev->dev, socdev->dev); | 344 | &pdev->dev, socdev->dev); |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index aea0cb72d80a..ac73e692a99b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -314,22 +314,6 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { | |||
314 | SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), | 314 | SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), |
315 | }; | 315 | }; |
316 | 316 | ||
317 | /* add non dapm controls */ | ||
318 | static int aic3x_add_controls(struct snd_soc_codec *codec) | ||
319 | { | ||
320 | int err, i; | ||
321 | |||
322 | for (i = 0; i < ARRAY_SIZE(aic3x_snd_controls); i++) { | ||
323 | err = snd_ctl_add(codec->card, | ||
324 | snd_soc_cnew(&aic3x_snd_controls[i], | ||
325 | codec, NULL)); | ||
326 | if (err < 0) | ||
327 | return err; | ||
328 | } | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /* Left DAC Mux */ | 317 | /* Left DAC Mux */ |
334 | static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = | 318 | static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = |
335 | SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]); | 319 | SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]); |
@@ -746,7 +730,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, | |||
746 | { | 730 | { |
747 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 731 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
748 | struct snd_soc_device *socdev = rtd->socdev; | 732 | struct snd_soc_device *socdev = rtd->socdev; |
749 | struct snd_soc_codec *codec = socdev->codec; | 733 | struct snd_soc_codec *codec = socdev->card->codec; |
750 | struct aic3x_priv *aic3x = codec->private_data; | 734 | struct aic3x_priv *aic3x = codec->private_data; |
751 | int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; | 735 | int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; |
752 | u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; | 736 | u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; |
@@ -1098,7 +1082,7 @@ EXPORT_SYMBOL_GPL(aic3x_dai); | |||
1098 | static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) | 1082 | static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) |
1099 | { | 1083 | { |
1100 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1084 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1101 | struct snd_soc_codec *codec = socdev->codec; | 1085 | struct snd_soc_codec *codec = socdev->card->codec; |
1102 | 1086 | ||
1103 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1087 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1104 | 1088 | ||
@@ -1108,7 +1092,7 @@ static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) | |||
1108 | static int aic3x_resume(struct platform_device *pdev) | 1092 | static int aic3x_resume(struct platform_device *pdev) |
1109 | { | 1093 | { |
1110 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1094 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1111 | struct snd_soc_codec *codec = socdev->codec; | 1095 | struct snd_soc_codec *codec = socdev->card->codec; |
1112 | int i; | 1096 | int i; |
1113 | u8 data[2]; | 1097 | u8 data[2]; |
1114 | u8 *cache = codec->reg_cache; | 1098 | u8 *cache = codec->reg_cache; |
@@ -1131,7 +1115,7 @@ static int aic3x_resume(struct platform_device *pdev) | |||
1131 | */ | 1115 | */ |
1132 | static int aic3x_init(struct snd_soc_device *socdev) | 1116 | static int aic3x_init(struct snd_soc_device *socdev) |
1133 | { | 1117 | { |
1134 | struct snd_soc_codec *codec = socdev->codec; | 1118 | struct snd_soc_codec *codec = socdev->card->codec; |
1135 | struct aic3x_setup_data *setup = socdev->codec_data; | 1119 | struct aic3x_setup_data *setup = socdev->codec_data; |
1136 | int reg, ret = 0; | 1120 | int reg, ret = 0; |
1137 | 1121 | ||
@@ -1227,7 +1211,8 @@ static int aic3x_init(struct snd_soc_device *socdev) | |||
1227 | aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); | 1211 | aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); |
1228 | aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); | 1212 | aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); |
1229 | 1213 | ||
1230 | aic3x_add_controls(codec); | 1214 | snd_soc_add_controls(codec, aic3x_snd_controls, |
1215 | ARRAY_SIZE(aic3x_snd_controls)); | ||
1231 | aic3x_add_widgets(codec); | 1216 | aic3x_add_widgets(codec); |
1232 | ret = snd_soc_init_card(socdev); | 1217 | ret = snd_soc_init_card(socdev); |
1233 | if (ret < 0) { | 1218 | if (ret < 0) { |
@@ -1261,7 +1246,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1261 | const struct i2c_device_id *id) | 1246 | const struct i2c_device_id *id) |
1262 | { | 1247 | { |
1263 | struct snd_soc_device *socdev = aic3x_socdev; | 1248 | struct snd_soc_device *socdev = aic3x_socdev; |
1264 | struct snd_soc_codec *codec = socdev->codec; | 1249 | struct snd_soc_codec *codec = socdev->card->codec; |
1265 | int ret; | 1250 | int ret; |
1266 | 1251 | ||
1267 | i2c_set_clientdata(i2c, codec); | 1252 | i2c_set_clientdata(i2c, codec); |
@@ -1366,7 +1351,7 @@ static int aic3x_probe(struct platform_device *pdev) | |||
1366 | } | 1351 | } |
1367 | 1352 | ||
1368 | codec->private_data = aic3x; | 1353 | codec->private_data = aic3x; |
1369 | socdev->codec = codec; | 1354 | socdev->card->codec = codec; |
1370 | mutex_init(&codec->mutex); | 1355 | mutex_init(&codec->mutex); |
1371 | INIT_LIST_HEAD(&codec->dapm_widgets); | 1356 | INIT_LIST_HEAD(&codec->dapm_widgets); |
1372 | INIT_LIST_HEAD(&codec->dapm_paths); | 1357 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -1392,7 +1377,7 @@ static int aic3x_probe(struct platform_device *pdev) | |||
1392 | static int aic3x_remove(struct platform_device *pdev) | 1377 | static int aic3x_remove(struct platform_device *pdev) |
1393 | { | 1378 | { |
1394 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1379 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1395 | struct snd_soc_codec *codec = socdev->codec; | 1380 | struct snd_soc_codec *codec = socdev->card->codec; |
1396 | 1381 | ||
1397 | /* power down chip */ | 1382 | /* power down chip */ |
1398 | if (codec->control_data) | 1383 | if (codec->control_data) |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index ea370a4f86d5..c26854b398d3 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { | 43 | static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { |
44 | 0x00, /* this register not used */ | 44 | 0x00, /* this register not used */ |
45 | 0x93, /* REG_CODEC_MODE (0x1) */ | 45 | 0x91, /* REG_CODEC_MODE (0x1) */ |
46 | 0xc3, /* REG_OPTION (0x2) */ | 46 | 0xc3, /* REG_OPTION (0x2) */ |
47 | 0x00, /* REG_UNKNOWN (0x3) */ | 47 | 0x00, /* REG_UNKNOWN (0x3) */ |
48 | 0x00, /* REG_MICBIAS_CTL (0x4) */ | 48 | 0x00, /* REG_MICBIAS_CTL (0x4) */ |
@@ -117,6 +117,13 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { | |||
117 | 0x00, /* REG_MISC_SET_2 (0x49) */ | 117 | 0x00, /* REG_MISC_SET_2 (0x49) */ |
118 | }; | 118 | }; |
119 | 119 | ||
120 | /* codec private data */ | ||
121 | struct twl4030_priv { | ||
122 | unsigned int bypass_state; | ||
123 | unsigned int codec_powered; | ||
124 | unsigned int codec_muted; | ||
125 | }; | ||
126 | |||
120 | /* | 127 | /* |
121 | * read twl4030 register cache | 128 | * read twl4030 register cache |
122 | */ | 129 | */ |
@@ -125,6 +132,9 @@ static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec, | |||
125 | { | 132 | { |
126 | u8 *cache = codec->reg_cache; | 133 | u8 *cache = codec->reg_cache; |
127 | 134 | ||
135 | if (reg >= TWL4030_CACHEREGNUM) | ||
136 | return -EIO; | ||
137 | |||
128 | return cache[reg]; | 138 | return cache[reg]; |
129 | } | 139 | } |
130 | 140 | ||
@@ -151,26 +161,22 @@ static int twl4030_write(struct snd_soc_codec *codec, | |||
151 | return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); | 161 | return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); |
152 | } | 162 | } |
153 | 163 | ||
154 | static void twl4030_clear_codecpdz(struct snd_soc_codec *codec) | 164 | static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) |
155 | { | 165 | { |
166 | struct twl4030_priv *twl4030 = codec->private_data; | ||
156 | u8 mode; | 167 | u8 mode; |
157 | 168 | ||
158 | mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); | 169 | if (enable == twl4030->codec_powered) |
159 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, | 170 | return; |
160 | mode & ~TWL4030_CODECPDZ); | ||
161 | |||
162 | /* REVISIT: this delay is present in TI sample drivers */ | ||
163 | /* but there seems to be no TRM requirement for it */ | ||
164 | udelay(10); | ||
165 | } | ||
166 | |||
167 | static void twl4030_set_codecpdz(struct snd_soc_codec *codec) | ||
168 | { | ||
169 | u8 mode; | ||
170 | 171 | ||
171 | mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); | 172 | mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); |
172 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, | 173 | if (enable) |
173 | mode | TWL4030_CODECPDZ); | 174 | mode |= TWL4030_CODECPDZ; |
175 | else | ||
176 | mode &= ~TWL4030_CODECPDZ; | ||
177 | |||
178 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); | ||
179 | twl4030->codec_powered = enable; | ||
174 | 180 | ||
175 | /* REVISIT: this delay is present in TI sample drivers */ | 181 | /* REVISIT: this delay is present in TI sample drivers */ |
176 | /* but there seems to be no TRM requirement for it */ | 182 | /* but there seems to be no TRM requirement for it */ |
@@ -182,7 +188,7 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) | |||
182 | int i; | 188 | int i; |
183 | 189 | ||
184 | /* clear CODECPDZ prior to setting register defaults */ | 190 | /* clear CODECPDZ prior to setting register defaults */ |
185 | twl4030_clear_codecpdz(codec); | 191 | twl4030_codec_enable(codec, 0); |
186 | 192 | ||
187 | /* set all audio section registers to reasonable defaults */ | 193 | /* set all audio section registers to reasonable defaults */ |
188 | for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) | 194 | for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) |
@@ -190,6 +196,122 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) | |||
190 | 196 | ||
191 | } | 197 | } |
192 | 198 | ||
199 | static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) | ||
200 | { | ||
201 | struct twl4030_priv *twl4030 = codec->private_data; | ||
202 | u8 reg_val; | ||
203 | |||
204 | if (mute == twl4030->codec_muted) | ||
205 | return; | ||
206 | |||
207 | if (mute) { | ||
208 | /* Bypass the reg_cache and mute the volumes | ||
209 | * Headset mute is done in it's own event handler | ||
210 | * Things to mute: Earpiece, PreDrivL/R, CarkitL/R | ||
211 | */ | ||
212 | reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL); | ||
213 | twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
214 | reg_val & (~TWL4030_EAR_GAIN), | ||
215 | TWL4030_REG_EAR_CTL); | ||
216 | |||
217 | reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL); | ||
218 | twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
219 | reg_val & (~TWL4030_PREDL_GAIN), | ||
220 | TWL4030_REG_PREDL_CTL); | ||
221 | reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL); | ||
222 | twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
223 | reg_val & (~TWL4030_PREDR_GAIN), | ||
224 | TWL4030_REG_PREDL_CTL); | ||
225 | |||
226 | reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL); | ||
227 | twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
228 | reg_val & (~TWL4030_PRECKL_GAIN), | ||
229 | TWL4030_REG_PRECKL_CTL); | ||
230 | reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL); | ||
231 | twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
232 | reg_val & (~TWL4030_PRECKL_GAIN), | ||
233 | TWL4030_REG_PRECKR_CTL); | ||
234 | |||
235 | /* Disable PLL */ | ||
236 | reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); | ||
237 | reg_val &= ~TWL4030_APLL_EN; | ||
238 | twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); | ||
239 | } else { | ||
240 | /* Restore the volumes | ||
241 | * Headset mute is done in it's own event handler | ||
242 | * Things to restore: Earpiece, PreDrivL/R, CarkitL/R | ||
243 | */ | ||
244 | twl4030_write(codec, TWL4030_REG_EAR_CTL, | ||
245 | twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL)); | ||
246 | |||
247 | twl4030_write(codec, TWL4030_REG_PREDL_CTL, | ||
248 | twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL)); | ||
249 | twl4030_write(codec, TWL4030_REG_PREDR_CTL, | ||
250 | twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL)); | ||
251 | |||
252 | twl4030_write(codec, TWL4030_REG_PRECKL_CTL, | ||
253 | twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL)); | ||
254 | twl4030_write(codec, TWL4030_REG_PRECKR_CTL, | ||
255 | twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL)); | ||
256 | |||
257 | /* Enable PLL */ | ||
258 | reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); | ||
259 | reg_val |= TWL4030_APLL_EN; | ||
260 | twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); | ||
261 | } | ||
262 | |||
263 | twl4030->codec_muted = mute; | ||
264 | } | ||
265 | |||
266 | static void twl4030_power_up(struct snd_soc_codec *codec) | ||
267 | { | ||
268 | struct twl4030_priv *twl4030 = codec->private_data; | ||
269 | u8 anamicl, regmisc1, byte; | ||
270 | int i = 0; | ||
271 | |||
272 | if (twl4030->codec_powered) | ||
273 | return; | ||
274 | |||
275 | /* set CODECPDZ to turn on codec */ | ||
276 | twl4030_codec_enable(codec, 1); | ||
277 | |||
278 | /* initiate offset cancellation */ | ||
279 | anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); | ||
280 | twl4030_write(codec, TWL4030_REG_ANAMICL, | ||
281 | anamicl | TWL4030_CNCL_OFFSET_START); | ||
282 | |||
283 | /* wait for offset cancellation to complete */ | ||
284 | do { | ||
285 | /* this takes a little while, so don't slam i2c */ | ||
286 | udelay(2000); | ||
287 | twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, | ||
288 | TWL4030_REG_ANAMICL); | ||
289 | } while ((i++ < 100) && | ||
290 | ((byte & TWL4030_CNCL_OFFSET_START) == | ||
291 | TWL4030_CNCL_OFFSET_START)); | ||
292 | |||
293 | /* Make sure that the reg_cache has the same value as the HW */ | ||
294 | twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte); | ||
295 | |||
296 | /* anti-pop when changing analog gain */ | ||
297 | regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1); | ||
298 | twl4030_write(codec, TWL4030_REG_MISC_SET_1, | ||
299 | regmisc1 | TWL4030_SMOOTH_ANAVOL_EN); | ||
300 | |||
301 | /* toggle CODECPDZ as per TRM */ | ||
302 | twl4030_codec_enable(codec, 0); | ||
303 | twl4030_codec_enable(codec, 1); | ||
304 | } | ||
305 | |||
306 | /* | ||
307 | * Unconditional power down | ||
308 | */ | ||
309 | static void twl4030_power_down(struct snd_soc_codec *codec) | ||
310 | { | ||
311 | /* power down */ | ||
312 | twl4030_codec_enable(codec, 0); | ||
313 | } | ||
314 | |||
193 | /* Earpiece */ | 315 | /* Earpiece */ |
194 | static const char *twl4030_earpiece_texts[] = | 316 | static const char *twl4030_earpiece_texts[] = |
195 | {"Off", "DACL1", "DACL2", "DACR1"}; | 317 | {"Off", "DACL1", "DACL2", "DACR1"}; |
@@ -366,6 +488,22 @@ static const struct soc_enum twl4030_micpathtx2_enum = | |||
366 | static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control = | 488 | static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control = |
367 | SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum); | 489 | SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum); |
368 | 490 | ||
491 | /* Analog bypass for AudioR1 */ | ||
492 | static const struct snd_kcontrol_new twl4030_dapm_abypassr1_control = | ||
493 | SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR1_APGA_CTL, 2, 1, 0); | ||
494 | |||
495 | /* Analog bypass for AudioL1 */ | ||
496 | static const struct snd_kcontrol_new twl4030_dapm_abypassl1_control = | ||
497 | SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL1_APGA_CTL, 2, 1, 0); | ||
498 | |||
499 | /* Analog bypass for AudioR2 */ | ||
500 | static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control = | ||
501 | SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR2_APGA_CTL, 2, 1, 0); | ||
502 | |||
503 | /* Analog bypass for AudioL2 */ | ||
504 | static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control = | ||
505 | SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0); | ||
506 | |||
369 | static int micpath_event(struct snd_soc_dapm_widget *w, | 507 | static int micpath_event(struct snd_soc_dapm_widget *w, |
370 | struct snd_kcontrol *kcontrol, int event) | 508 | struct snd_kcontrol *kcontrol, int event) |
371 | { | 509 | { |
@@ -420,6 +558,72 @@ static int handsfree_event(struct snd_soc_dapm_widget *w, | |||
420 | return 0; | 558 | return 0; |
421 | } | 559 | } |
422 | 560 | ||
561 | static int headsetl_event(struct snd_soc_dapm_widget *w, | ||
562 | struct snd_kcontrol *kcontrol, int event) | ||
563 | { | ||
564 | unsigned char hs_gain, hs_pop; | ||
565 | |||
566 | /* Save the current volume */ | ||
567 | hs_gain = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_GAIN_SET); | ||
568 | |||
569 | switch (event) { | ||
570 | case SND_SOC_DAPM_POST_PMU: | ||
571 | /* Do the anti-pop/bias ramp enable according to the TRM */ | ||
572 | hs_pop = TWL4030_RAMP_DELAY_645MS; | ||
573 | twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); | ||
574 | hs_pop |= TWL4030_VMID_EN; | ||
575 | twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); | ||
576 | /* Is this needed? Can we just use whatever gain here? */ | ||
577 | twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET, | ||
578 | (hs_gain & (~0x0f)) | 0x0a); | ||
579 | hs_pop |= TWL4030_RAMP_EN; | ||
580 | twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); | ||
581 | |||
582 | /* Restore the original volume */ | ||
583 | twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET, hs_gain); | ||
584 | break; | ||
585 | case SND_SOC_DAPM_POST_PMD: | ||
586 | /* Do the anti-pop/bias ramp disable according to the TRM */ | ||
587 | hs_pop = twl4030_read_reg_cache(w->codec, | ||
588 | TWL4030_REG_HS_POPN_SET); | ||
589 | hs_pop &= ~TWL4030_RAMP_EN; | ||
590 | twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); | ||
591 | /* Bypass the reg_cache to mute the headset */ | ||
592 | twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
593 | hs_gain & (~0x0f), | ||
594 | TWL4030_REG_HS_GAIN_SET); | ||
595 | hs_pop &= ~TWL4030_VMID_EN; | ||
596 | twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); | ||
597 | break; | ||
598 | } | ||
599 | return 0; | ||
600 | } | ||
601 | |||
602 | static int bypass_event(struct snd_soc_dapm_widget *w, | ||
603 | struct snd_kcontrol *kcontrol, int event) | ||
604 | { | ||
605 | struct soc_mixer_control *m = | ||
606 | (struct soc_mixer_control *)w->kcontrols->private_value; | ||
607 | struct twl4030_priv *twl4030 = w->codec->private_data; | ||
608 | unsigned char reg; | ||
609 | |||
610 | reg = twl4030_read_reg_cache(w->codec, m->reg); | ||
611 | if (reg & (1 << m->shift)) | ||
612 | twl4030->bypass_state |= | ||
613 | (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); | ||
614 | else | ||
615 | twl4030->bypass_state &= | ||
616 | ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); | ||
617 | |||
618 | if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) { | ||
619 | if (twl4030->bypass_state) | ||
620 | twl4030_codec_mute(w->codec, 0); | ||
621 | else | ||
622 | twl4030_codec_mute(w->codec, 1); | ||
623 | } | ||
624 | return 0; | ||
625 | } | ||
626 | |||
423 | /* | 627 | /* |
424 | * Some of the gain controls in TWL (mostly those which are associated with | 628 | * Some of the gain controls in TWL (mostly those which are associated with |
425 | * the outputs) are implemented in an interesting way: | 629 | * the outputs) are implemented in an interesting way: |
@@ -670,22 +874,6 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { | |||
670 | 0, 3, 5, 0, input_gain_tlv), | 874 | 0, 3, 5, 0, input_gain_tlv), |
671 | }; | 875 | }; |
672 | 876 | ||
673 | /* add non dapm controls */ | ||
674 | static int twl4030_add_controls(struct snd_soc_codec *codec) | ||
675 | { | ||
676 | int err, i; | ||
677 | |||
678 | for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) { | ||
679 | err = snd_ctl_add(codec->card, | ||
680 | snd_soc_cnew(&twl4030_snd_controls[i], | ||
681 | codec, NULL)); | ||
682 | if (err < 0) | ||
683 | return err; | ||
684 | } | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | 877 | static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { |
690 | /* Left channel inputs */ | 878 | /* Left channel inputs */ |
691 | SND_SOC_DAPM_INPUT("MAINMIC"), | 879 | SND_SOC_DAPM_INPUT("MAINMIC"), |
@@ -714,13 +902,13 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
714 | 902 | ||
715 | /* DACs */ | 903 | /* DACs */ |
716 | SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", | 904 | SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", |
717 | TWL4030_REG_AVDAC_CTL, 0, 0), | 905 | SND_SOC_NOPM, 0, 0), |
718 | SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback", | 906 | SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback", |
719 | TWL4030_REG_AVDAC_CTL, 1, 0), | 907 | SND_SOC_NOPM, 0, 0), |
720 | SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback", | 908 | SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback", |
721 | TWL4030_REG_AVDAC_CTL, 2, 0), | 909 | SND_SOC_NOPM, 0, 0), |
722 | SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", | 910 | SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", |
723 | TWL4030_REG_AVDAC_CTL, 3, 0), | 911 | SND_SOC_NOPM, 0, 0), |
724 | 912 | ||
725 | /* Analog PGAs */ | 913 | /* Analog PGAs */ |
726 | SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, | 914 | SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, |
@@ -732,6 +920,29 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
732 | SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL, | 920 | SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL, |
733 | 0, 0, NULL, 0), | 921 | 0, 0, NULL, 0), |
734 | 922 | ||
923 | /* Analog bypasses */ | ||
924 | SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, | ||
925 | &twl4030_dapm_abypassr1_control, bypass_event, | ||
926 | SND_SOC_DAPM_POST_REG), | ||
927 | SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0, | ||
928 | &twl4030_dapm_abypassl1_control, | ||
929 | bypass_event, SND_SOC_DAPM_POST_REG), | ||
930 | SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0, | ||
931 | &twl4030_dapm_abypassr2_control, | ||
932 | bypass_event, SND_SOC_DAPM_POST_REG), | ||
933 | SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, | ||
934 | &twl4030_dapm_abypassl2_control, | ||
935 | bypass_event, SND_SOC_DAPM_POST_REG), | ||
936 | |||
937 | SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL, | ||
938 | 0, 0, NULL, 0), | ||
939 | SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer", TWL4030_REG_AVDAC_CTL, | ||
940 | 1, 0, NULL, 0), | ||
941 | SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer", TWL4030_REG_AVDAC_CTL, | ||
942 | 2, 0, NULL, 0), | ||
943 | SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, | ||
944 | 3, 0, NULL, 0), | ||
945 | |||
735 | /* Output MUX controls */ | 946 | /* Output MUX controls */ |
736 | /* Earpiece */ | 947 | /* Earpiece */ |
737 | SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0, | 948 | SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0, |
@@ -742,8 +953,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
742 | SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0, | 953 | SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0, |
743 | &twl4030_dapm_predriver_control), | 954 | &twl4030_dapm_predriver_control), |
744 | /* HeadsetL/R */ | 955 | /* HeadsetL/R */ |
745 | SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0, | 956 | SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0, |
746 | &twl4030_dapm_hsol_control), | 957 | &twl4030_dapm_hsol_control, headsetl_event, |
958 | SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), | ||
747 | SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, | 959 | SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, |
748 | &twl4030_dapm_hsor_control), | 960 | &twl4030_dapm_hsor_control), |
749 | /* CarkitL/R */ | 961 | /* CarkitL/R */ |
@@ -782,16 +994,16 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
782 | SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD| | 994 | SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD| |
783 | SND_SOC_DAPM_POST_REG), | 995 | SND_SOC_DAPM_POST_REG), |
784 | 996 | ||
785 | /* Analog input muxes with power switch for the physical ADCL/R */ | 997 | /* Analog input muxes with switch for the capture amplifiers */ |
786 | SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route", | 998 | SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route", |
787 | TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control), | 999 | TWL4030_REG_ANAMICL, 4, 0, &twl4030_dapm_analoglmic_control), |
788 | SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route", | 1000 | SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route", |
789 | TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control), | 1001 | TWL4030_REG_ANAMICR, 4, 0, &twl4030_dapm_analogrmic_control), |
790 | 1002 | ||
791 | SND_SOC_DAPM_PGA("Analog Left Amplifier", | 1003 | SND_SOC_DAPM_PGA("ADC Physical Left", |
792 | TWL4030_REG_ANAMICL, 4, 0, NULL, 0), | 1004 | TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0), |
793 | SND_SOC_DAPM_PGA("Analog Right Amplifier", | 1005 | SND_SOC_DAPM_PGA("ADC Physical Right", |
794 | TWL4030_REG_ANAMICR, 4, 0, NULL, 0), | 1006 | TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0), |
795 | 1007 | ||
796 | SND_SOC_DAPM_PGA("Digimic0 Enable", | 1008 | SND_SOC_DAPM_PGA("Digimic0 Enable", |
797 | TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0), | 1009 | TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0), |
@@ -801,13 +1013,19 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
801 | SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), | 1013 | SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), |
802 | SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), | 1014 | SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), |
803 | SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0), | 1015 | SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0), |
1016 | |||
804 | }; | 1017 | }; |
805 | 1018 | ||
806 | static const struct snd_soc_dapm_route intercon[] = { | 1019 | static const struct snd_soc_dapm_route intercon[] = { |
807 | {"ARXL1_APGA", NULL, "DAC Left1"}, | 1020 | {"Analog L1 Playback Mixer", NULL, "DAC Left1"}, |
808 | {"ARXR1_APGA", NULL, "DAC Right1"}, | 1021 | {"Analog R1 Playback Mixer", NULL, "DAC Right1"}, |
809 | {"ARXL2_APGA", NULL, "DAC Left2"}, | 1022 | {"Analog L2 Playback Mixer", NULL, "DAC Left2"}, |
810 | {"ARXR2_APGA", NULL, "DAC Right2"}, | 1023 | {"Analog R2 Playback Mixer", NULL, "DAC Right2"}, |
1024 | |||
1025 | {"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"}, | ||
1026 | {"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"}, | ||
1027 | {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"}, | ||
1028 | {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"}, | ||
811 | 1029 | ||
812 | /* Internal playback routings */ | 1030 | /* Internal playback routings */ |
813 | /* Earpiece */ | 1031 | /* Earpiece */ |
@@ -865,23 +1083,23 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
865 | {"Analog Right Capture Route", "Sub mic", "SUBMIC"}, | 1083 | {"Analog Right Capture Route", "Sub mic", "SUBMIC"}, |
866 | {"Analog Right Capture Route", "AUXR", "AUXR"}, | 1084 | {"Analog Right Capture Route", "AUXR", "AUXR"}, |
867 | 1085 | ||
868 | {"Analog Left Amplifier", NULL, "Analog Left Capture Route"}, | 1086 | {"ADC Physical Left", NULL, "Analog Left Capture Route"}, |
869 | {"Analog Right Amplifier", NULL, "Analog Right Capture Route"}, | 1087 | {"ADC Physical Right", NULL, "Analog Right Capture Route"}, |
870 | 1088 | ||
871 | {"Digimic0 Enable", NULL, "DIGIMIC0"}, | 1089 | {"Digimic0 Enable", NULL, "DIGIMIC0"}, |
872 | {"Digimic1 Enable", NULL, "DIGIMIC1"}, | 1090 | {"Digimic1 Enable", NULL, "DIGIMIC1"}, |
873 | 1091 | ||
874 | /* TX1 Left capture path */ | 1092 | /* TX1 Left capture path */ |
875 | {"TX1 Capture Route", "Analog", "Analog Left Amplifier"}, | 1093 | {"TX1 Capture Route", "Analog", "ADC Physical Left"}, |
876 | {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, | 1094 | {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, |
877 | /* TX1 Right capture path */ | 1095 | /* TX1 Right capture path */ |
878 | {"TX1 Capture Route", "Analog", "Analog Right Amplifier"}, | 1096 | {"TX1 Capture Route", "Analog", "ADC Physical Right"}, |
879 | {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, | 1097 | {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, |
880 | /* TX2 Left capture path */ | 1098 | /* TX2 Left capture path */ |
881 | {"TX2 Capture Route", "Analog", "Analog Left Amplifier"}, | 1099 | {"TX2 Capture Route", "Analog", "ADC Physical Left"}, |
882 | {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"}, | 1100 | {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"}, |
883 | /* TX2 Right capture path */ | 1101 | /* TX2 Right capture path */ |
884 | {"TX2 Capture Route", "Analog", "Analog Right Amplifier"}, | 1102 | {"TX2 Capture Route", "Analog", "ADC Physical Right"}, |
885 | {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"}, | 1103 | {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"}, |
886 | 1104 | ||
887 | {"ADC Virtual Left1", NULL, "TX1 Capture Route"}, | 1105 | {"ADC Virtual Left1", NULL, "TX1 Capture Route"}, |
@@ -889,6 +1107,17 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
889 | {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, | 1107 | {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, |
890 | {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, | 1108 | {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, |
891 | 1109 | ||
1110 | /* Analog bypass routes */ | ||
1111 | {"Right1 Analog Loopback", "Switch", "Analog Right Capture Route"}, | ||
1112 | {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, | ||
1113 | {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, | ||
1114 | {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, | ||
1115 | |||
1116 | {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, | ||
1117 | {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, | ||
1118 | {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, | ||
1119 | {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"}, | ||
1120 | |||
892 | }; | 1121 | }; |
893 | 1122 | ||
894 | static int twl4030_add_widgets(struct snd_soc_codec *codec) | 1123 | static int twl4030_add_widgets(struct snd_soc_codec *codec) |
@@ -902,82 +1131,28 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec) | |||
902 | return 0; | 1131 | return 0; |
903 | } | 1132 | } |
904 | 1133 | ||
905 | static void twl4030_power_up(struct snd_soc_codec *codec) | ||
906 | { | ||
907 | u8 anamicl, regmisc1, byte, popn; | ||
908 | int i = 0; | ||
909 | |||
910 | /* set CODECPDZ to turn on codec */ | ||
911 | twl4030_set_codecpdz(codec); | ||
912 | |||
913 | /* initiate offset cancellation */ | ||
914 | anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); | ||
915 | twl4030_write(codec, TWL4030_REG_ANAMICL, | ||
916 | anamicl | TWL4030_CNCL_OFFSET_START); | ||
917 | |||
918 | |||
919 | /* wait for offset cancellation to complete */ | ||
920 | do { | ||
921 | /* this takes a little while, so don't slam i2c */ | ||
922 | udelay(2000); | ||
923 | twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, | ||
924 | TWL4030_REG_ANAMICL); | ||
925 | } while ((i++ < 100) && | ||
926 | ((byte & TWL4030_CNCL_OFFSET_START) == | ||
927 | TWL4030_CNCL_OFFSET_START)); | ||
928 | |||
929 | /* anti-pop when changing analog gain */ | ||
930 | regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1); | ||
931 | twl4030_write(codec, TWL4030_REG_MISC_SET_1, | ||
932 | regmisc1 | TWL4030_SMOOTH_ANAVOL_EN); | ||
933 | |||
934 | /* toggle CODECPDZ as per TRM */ | ||
935 | twl4030_clear_codecpdz(codec); | ||
936 | twl4030_set_codecpdz(codec); | ||
937 | |||
938 | /* program anti-pop with bias ramp delay */ | ||
939 | popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); | ||
940 | popn &= TWL4030_RAMP_DELAY; | ||
941 | popn |= TWL4030_RAMP_DELAY_645MS; | ||
942 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); | ||
943 | popn |= TWL4030_VMID_EN; | ||
944 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); | ||
945 | |||
946 | /* enable anti-pop ramp */ | ||
947 | popn |= TWL4030_RAMP_EN; | ||
948 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); | ||
949 | } | ||
950 | |||
951 | static void twl4030_power_down(struct snd_soc_codec *codec) | ||
952 | { | ||
953 | u8 popn; | ||
954 | |||
955 | /* disable anti-pop ramp */ | ||
956 | popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); | ||
957 | popn &= ~TWL4030_RAMP_EN; | ||
958 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); | ||
959 | |||
960 | /* disable bias out */ | ||
961 | popn &= ~TWL4030_VMID_EN; | ||
962 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); | ||
963 | |||
964 | /* power down */ | ||
965 | twl4030_clear_codecpdz(codec); | ||
966 | } | ||
967 | |||
968 | static int twl4030_set_bias_level(struct snd_soc_codec *codec, | 1134 | static int twl4030_set_bias_level(struct snd_soc_codec *codec, |
969 | enum snd_soc_bias_level level) | 1135 | enum snd_soc_bias_level level) |
970 | { | 1136 | { |
1137 | struct twl4030_priv *twl4030 = codec->private_data; | ||
1138 | |||
971 | switch (level) { | 1139 | switch (level) { |
972 | case SND_SOC_BIAS_ON: | 1140 | case SND_SOC_BIAS_ON: |
973 | twl4030_power_up(codec); | 1141 | twl4030_codec_mute(codec, 0); |
974 | break; | 1142 | break; |
975 | case SND_SOC_BIAS_PREPARE: | 1143 | case SND_SOC_BIAS_PREPARE: |
976 | /* TODO: develop a twl4030_prepare function */ | 1144 | twl4030_power_up(codec); |
1145 | if (twl4030->bypass_state) | ||
1146 | twl4030_codec_mute(codec, 0); | ||
1147 | else | ||
1148 | twl4030_codec_mute(codec, 1); | ||
977 | break; | 1149 | break; |
978 | case SND_SOC_BIAS_STANDBY: | 1150 | case SND_SOC_BIAS_STANDBY: |
979 | /* TODO: develop a twl4030_standby function */ | 1151 | twl4030_power_up(codec); |
980 | twl4030_power_down(codec); | 1152 | if (twl4030->bypass_state) |
1153 | twl4030_codec_mute(codec, 0); | ||
1154 | else | ||
1155 | twl4030_codec_mute(codec, 1); | ||
981 | break; | 1156 | break; |
982 | case SND_SOC_BIAS_OFF: | 1157 | case SND_SOC_BIAS_OFF: |
983 | twl4030_power_down(codec); | 1158 | twl4030_power_down(codec); |
@@ -994,10 +1169,9 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
994 | { | 1169 | { |
995 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1170 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
996 | struct snd_soc_device *socdev = rtd->socdev; | 1171 | struct snd_soc_device *socdev = rtd->socdev; |
997 | struct snd_soc_codec *codec = socdev->codec; | 1172 | struct snd_soc_codec *codec = socdev->card->codec; |
998 | u8 mode, old_mode, format, old_format; | 1173 | u8 mode, old_mode, format, old_format; |
999 | 1174 | ||
1000 | |||
1001 | /* bit rate */ | 1175 | /* bit rate */ |
1002 | old_mode = twl4030_read_reg_cache(codec, | 1176 | old_mode = twl4030_read_reg_cache(codec, |
1003 | TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; | 1177 | TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; |
@@ -1039,8 +1213,9 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1039 | 1213 | ||
1040 | if (mode != old_mode) { | 1214 | if (mode != old_mode) { |
1041 | /* change rate and set CODECPDZ */ | 1215 | /* change rate and set CODECPDZ */ |
1216 | twl4030_codec_enable(codec, 0); | ||
1042 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); | 1217 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); |
1043 | twl4030_set_codecpdz(codec); | 1218 | twl4030_codec_enable(codec, 1); |
1044 | } | 1219 | } |
1045 | 1220 | ||
1046 | /* sample size */ | 1221 | /* sample size */ |
@@ -1063,13 +1238,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1063 | if (format != old_format) { | 1238 | if (format != old_format) { |
1064 | 1239 | ||
1065 | /* clear CODECPDZ before changing format (codec requirement) */ | 1240 | /* clear CODECPDZ before changing format (codec requirement) */ |
1066 | twl4030_clear_codecpdz(codec); | 1241 | twl4030_codec_enable(codec, 0); |
1067 | 1242 | ||
1068 | /* change format */ | 1243 | /* change format */ |
1069 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); | 1244 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); |
1070 | 1245 | ||
1071 | /* set CODECPDZ afterwards */ | 1246 | /* set CODECPDZ afterwards */ |
1072 | twl4030_set_codecpdz(codec); | 1247 | twl4030_codec_enable(codec, 1); |
1073 | } | 1248 | } |
1074 | return 0; | 1249 | return 0; |
1075 | } | 1250 | } |
@@ -1139,13 +1314,13 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1139 | if (format != old_format) { | 1314 | if (format != old_format) { |
1140 | 1315 | ||
1141 | /* clear CODECPDZ before changing format (codec requirement) */ | 1316 | /* clear CODECPDZ before changing format (codec requirement) */ |
1142 | twl4030_clear_codecpdz(codec); | 1317 | twl4030_codec_enable(codec, 0); |
1143 | 1318 | ||
1144 | /* change format */ | 1319 | /* change format */ |
1145 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); | 1320 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); |
1146 | 1321 | ||
1147 | /* set CODECPDZ afterwards */ | 1322 | /* set CODECPDZ afterwards */ |
1148 | twl4030_set_codecpdz(codec); | 1323 | twl4030_codec_enable(codec, 1); |
1149 | } | 1324 | } |
1150 | 1325 | ||
1151 | return 0; | 1326 | return 0; |
@@ -1179,7 +1354,7 @@ EXPORT_SYMBOL_GPL(twl4030_dai); | |||
1179 | static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) | 1354 | static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) |
1180 | { | 1355 | { |
1181 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1356 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1182 | struct snd_soc_codec *codec = socdev->codec; | 1357 | struct snd_soc_codec *codec = socdev->card->codec; |
1183 | 1358 | ||
1184 | twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1359 | twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1185 | 1360 | ||
@@ -1189,7 +1364,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) | |||
1189 | static int twl4030_resume(struct platform_device *pdev) | 1364 | static int twl4030_resume(struct platform_device *pdev) |
1190 | { | 1365 | { |
1191 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1366 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1192 | struct snd_soc_codec *codec = socdev->codec; | 1367 | struct snd_soc_codec *codec = socdev->card->codec; |
1193 | 1368 | ||
1194 | twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1369 | twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1195 | twl4030_set_bias_level(codec, codec->suspend_bias_level); | 1370 | twl4030_set_bias_level(codec, codec->suspend_bias_level); |
@@ -1203,7 +1378,7 @@ static int twl4030_resume(struct platform_device *pdev) | |||
1203 | 1378 | ||
1204 | static int twl4030_init(struct snd_soc_device *socdev) | 1379 | static int twl4030_init(struct snd_soc_device *socdev) |
1205 | { | 1380 | { |
1206 | struct snd_soc_codec *codec = socdev->codec; | 1381 | struct snd_soc_codec *codec = socdev->card->codec; |
1207 | int ret = 0; | 1382 | int ret = 0; |
1208 | 1383 | ||
1209 | printk(KERN_INFO "TWL4030 Audio Codec init \n"); | 1384 | printk(KERN_INFO "TWL4030 Audio Codec init \n"); |
@@ -1233,7 +1408,8 @@ static int twl4030_init(struct snd_soc_device *socdev) | |||
1233 | /* power on device */ | 1408 | /* power on device */ |
1234 | twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1409 | twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1235 | 1410 | ||
1236 | twl4030_add_controls(codec); | 1411 | snd_soc_add_controls(codec, twl4030_snd_controls, |
1412 | ARRAY_SIZE(twl4030_snd_controls)); | ||
1237 | twl4030_add_widgets(codec); | 1413 | twl4030_add_widgets(codec); |
1238 | 1414 | ||
1239 | ret = snd_soc_init_card(socdev); | 1415 | ret = snd_soc_init_card(socdev); |
@@ -1258,12 +1434,20 @@ static int twl4030_probe(struct platform_device *pdev) | |||
1258 | { | 1434 | { |
1259 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1435 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1260 | struct snd_soc_codec *codec; | 1436 | struct snd_soc_codec *codec; |
1437 | struct twl4030_priv *twl4030; | ||
1261 | 1438 | ||
1262 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 1439 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); |
1263 | if (codec == NULL) | 1440 | if (codec == NULL) |
1264 | return -ENOMEM; | 1441 | return -ENOMEM; |
1265 | 1442 | ||
1266 | socdev->codec = codec; | 1443 | twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); |
1444 | if (twl4030 == NULL) { | ||
1445 | kfree(codec); | ||
1446 | return -ENOMEM; | ||
1447 | } | ||
1448 | |||
1449 | codec->private_data = twl4030; | ||
1450 | socdev->card->codec = codec; | ||
1267 | mutex_init(&codec->mutex); | 1451 | mutex_init(&codec->mutex); |
1268 | INIT_LIST_HEAD(&codec->dapm_widgets); | 1452 | INIT_LIST_HEAD(&codec->dapm_widgets); |
1269 | INIT_LIST_HEAD(&codec->dapm_paths); | 1453 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -1277,11 +1461,13 @@ static int twl4030_probe(struct platform_device *pdev) | |||
1277 | static int twl4030_remove(struct platform_device *pdev) | 1461 | static int twl4030_remove(struct platform_device *pdev) |
1278 | { | 1462 | { |
1279 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1463 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1280 | struct snd_soc_codec *codec = socdev->codec; | 1464 | struct snd_soc_codec *codec = socdev->card->codec; |
1281 | 1465 | ||
1282 | printk(KERN_INFO "TWL4030 Audio Codec remove\n"); | 1466 | printk(KERN_INFO "TWL4030 Audio Codec remove\n"); |
1467 | twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1283 | snd_soc_free_pcms(socdev); | 1468 | snd_soc_free_pcms(socdev); |
1284 | snd_soc_dapm_free(socdev); | 1469 | snd_soc_dapm_free(socdev); |
1470 | kfree(codec->private_data); | ||
1285 | kfree(codec); | 1471 | kfree(codec); |
1286 | 1472 | ||
1287 | return 0; | 1473 | return 0; |
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h index 442e5a828617..33dbb144dad1 100644 --- a/sound/soc/codecs/twl4030.h +++ b/sound/soc/codecs/twl4030.h | |||
@@ -170,6 +170,9 @@ | |||
170 | #define TWL4030_CLK256FS_EN 0x02 | 170 | #define TWL4030_CLK256FS_EN 0x02 |
171 | #define TWL4030_AIF_EN 0x01 | 171 | #define TWL4030_AIF_EN 0x01 |
172 | 172 | ||
173 | /* EAR_CTL (0x21) */ | ||
174 | #define TWL4030_EAR_GAIN 0x30 | ||
175 | |||
173 | /* HS_GAIN_SET (0x23) Fields */ | 176 | /* HS_GAIN_SET (0x23) Fields */ |
174 | 177 | ||
175 | #define TWL4030_HSR_GAIN 0x0C | 178 | #define TWL4030_HSR_GAIN 0x0C |
@@ -198,6 +201,18 @@ | |||
198 | #define TWL4030_RAMP_DELAY_2581MS 0x1C | 201 | #define TWL4030_RAMP_DELAY_2581MS 0x1C |
199 | #define TWL4030_RAMP_EN 0x02 | 202 | #define TWL4030_RAMP_EN 0x02 |
200 | 203 | ||
204 | /* PREDL_CTL (0x25) */ | ||
205 | #define TWL4030_PREDL_GAIN 0x30 | ||
206 | |||
207 | /* PREDR_CTL (0x26) */ | ||
208 | #define TWL4030_PREDR_GAIN 0x30 | ||
209 | |||
210 | /* PRECKL_CTL (0x27) */ | ||
211 | #define TWL4030_PRECKL_GAIN 0x30 | ||
212 | |||
213 | /* PRECKR_CTL (0x28) */ | ||
214 | #define TWL4030_PRECKR_GAIN 0x30 | ||
215 | |||
201 | /* HFL_CTL (0x29, 0x2A) Fields */ | 216 | /* HFL_CTL (0x29, 0x2A) Fields */ |
202 | #define TWL4030_HF_CTL_HB_EN 0x04 | 217 | #define TWL4030_HF_CTL_HB_EN 0x04 |
203 | #define TWL4030_HF_CTL_LOOP_EN 0x08 | 218 | #define TWL4030_HF_CTL_LOOP_EN 0x08 |
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index a2c5064a774b..661599295ca7 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c | |||
@@ -173,7 +173,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream, | |||
173 | { | 173 | { |
174 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 174 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
175 | struct snd_soc_device *socdev = rtd->socdev; | 175 | struct snd_soc_device *socdev = rtd->socdev; |
176 | struct snd_soc_codec *codec = socdev->codec; | 176 | struct snd_soc_codec *codec = socdev->card->codec; |
177 | struct uda134x_priv *uda134x = codec->private_data; | 177 | struct uda134x_priv *uda134x = codec->private_data; |
178 | struct snd_pcm_runtime *master_runtime; | 178 | struct snd_pcm_runtime *master_runtime; |
179 | 179 | ||
@@ -206,7 +206,7 @@ static void uda134x_shutdown(struct snd_pcm_substream *substream, | |||
206 | { | 206 | { |
207 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 207 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
208 | struct snd_soc_device *socdev = rtd->socdev; | 208 | struct snd_soc_device *socdev = rtd->socdev; |
209 | struct snd_soc_codec *codec = socdev->codec; | 209 | struct snd_soc_codec *codec = socdev->card->codec; |
210 | struct uda134x_priv *uda134x = codec->private_data; | 210 | struct uda134x_priv *uda134x = codec->private_data; |
211 | 211 | ||
212 | if (uda134x->master_substream == substream) | 212 | if (uda134x->master_substream == substream) |
@@ -221,7 +221,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, | |||
221 | { | 221 | { |
222 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 222 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
223 | struct snd_soc_device *socdev = rtd->socdev; | 223 | struct snd_soc_device *socdev = rtd->socdev; |
224 | struct snd_soc_codec *codec = socdev->codec; | 224 | struct snd_soc_codec *codec = socdev->card->codec; |
225 | struct uda134x_priv *uda134x = codec->private_data; | 225 | struct uda134x_priv *uda134x = codec->private_data; |
226 | u8 hw_params; | 226 | u8 hw_params; |
227 | 227 | ||
@@ -431,39 +431,6 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]), | |||
431 | SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), | 431 | SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), |
432 | }; | 432 | }; |
433 | 433 | ||
434 | static int uda134x_add_controls(struct snd_soc_codec *codec) | ||
435 | { | ||
436 | int err, i, n; | ||
437 | const struct snd_kcontrol_new *ctrls; | ||
438 | struct uda134x_platform_data *pd = codec->control_data; | ||
439 | |||
440 | switch (pd->model) { | ||
441 | case UDA134X_UDA1340: | ||
442 | case UDA134X_UDA1344: | ||
443 | n = ARRAY_SIZE(uda1340_snd_controls); | ||
444 | ctrls = uda1340_snd_controls; | ||
445 | break; | ||
446 | case UDA134X_UDA1341: | ||
447 | n = ARRAY_SIZE(uda1341_snd_controls); | ||
448 | ctrls = uda1341_snd_controls; | ||
449 | break; | ||
450 | default: | ||
451 | printk(KERN_ERR "%s unkown codec type: %d", | ||
452 | __func__, pd->model); | ||
453 | return -EINVAL; | ||
454 | } | ||
455 | |||
456 | for (i = 0; i < n; i++) { | ||
457 | err = snd_ctl_add(codec->card, | ||
458 | snd_soc_cnew(&ctrls[i], | ||
459 | codec, NULL)); | ||
460 | if (err < 0) | ||
461 | return err; | ||
462 | } | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | struct snd_soc_dai uda134x_dai = { | 434 | struct snd_soc_dai uda134x_dai = { |
468 | .name = "UDA134X", | 435 | .name = "UDA134X", |
469 | /* playback capabilities */ | 436 | /* playback capabilities */ |
@@ -525,11 +492,11 @@ static int uda134x_soc_probe(struct platform_device *pdev) | |||
525 | return -EINVAL; | 492 | return -EINVAL; |
526 | } | 493 | } |
527 | 494 | ||
528 | socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 495 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); |
529 | if (socdev->codec == NULL) | 496 | if (socdev->card->codec == NULL) |
530 | return ret; | 497 | return ret; |
531 | 498 | ||
532 | codec = socdev->codec; | 499 | codec = socdev->card->codec; |
533 | 500 | ||
534 | uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); | 501 | uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); |
535 | if (uda134x == NULL) | 502 | if (uda134x == NULL) |
@@ -572,7 +539,22 @@ static int uda134x_soc_probe(struct platform_device *pdev) | |||
572 | goto pcm_err; | 539 | goto pcm_err; |
573 | } | 540 | } |
574 | 541 | ||
575 | ret = uda134x_add_controls(codec); | 542 | switch (pd->model) { |
543 | case UDA134X_UDA1340: | ||
544 | case UDA134X_UDA1344: | ||
545 | ret = snd_soc_add_controls(codec, uda1340_snd_controls, | ||
546 | ARRAY_SIZE(uda1340_snd_controls)); | ||
547 | break; | ||
548 | case UDA134X_UDA1341: | ||
549 | ret = snd_soc_add_controls(codec, uda1341_snd_controls, | ||
550 | ARRAY_SIZE(uda1341_snd_controls)); | ||
551 | break; | ||
552 | default: | ||
553 | printk(KERN_ERR "%s unkown codec type: %d", | ||
554 | __func__, pd->model); | ||
555 | return -EINVAL; | ||
556 | } | ||
557 | |||
576 | if (ret < 0) { | 558 | if (ret < 0) { |
577 | printk(KERN_ERR "UDA134X: failed to register controls\n"); | 559 | printk(KERN_ERR "UDA134X: failed to register controls\n"); |
578 | goto pcm_err; | 560 | goto pcm_err; |
@@ -602,7 +584,7 @@ priv_err: | |||
602 | static int uda134x_soc_remove(struct platform_device *pdev) | 584 | static int uda134x_soc_remove(struct platform_device *pdev) |
603 | { | 585 | { |
604 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 586 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
605 | struct snd_soc_codec *codec = socdev->codec; | 587 | struct snd_soc_codec *codec = socdev->card->codec; |
606 | 588 | ||
607 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 589 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
608 | uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); | 590 | uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
@@ -622,7 +604,7 @@ static int uda134x_soc_suspend(struct platform_device *pdev, | |||
622 | pm_message_t state) | 604 | pm_message_t state) |
623 | { | 605 | { |
624 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 606 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
625 | struct snd_soc_codec *codec = socdev->codec; | 607 | struct snd_soc_codec *codec = socdev->card->codec; |
626 | 608 | ||
627 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 609 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
628 | uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); | 610 | uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
@@ -632,7 +614,7 @@ static int uda134x_soc_suspend(struct platform_device *pdev, | |||
632 | static int uda134x_soc_resume(struct platform_device *pdev) | 614 | static int uda134x_soc_resume(struct platform_device *pdev) |
633 | { | 615 | { |
634 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 616 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
635 | struct snd_soc_codec *codec = socdev->codec; | 617 | struct snd_soc_codec *codec = socdev->card->codec; |
636 | 618 | ||
637 | uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); | 619 | uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); |
638 | uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); | 620 | uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); |
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index e6bf0844fbf3..5242b8156b38 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -271,21 +271,6 @@ static const struct snd_kcontrol_new uda1380_snd_controls[] = { | |||
271 | SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0), | 271 | SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0), |
272 | }; | 272 | }; |
273 | 273 | ||
274 | /* add non dapm controls */ | ||
275 | static int uda1380_add_controls(struct snd_soc_codec *codec) | ||
276 | { | ||
277 | int err, i; | ||
278 | |||
279 | for (i = 0; i < ARRAY_SIZE(uda1380_snd_controls); i++) { | ||
280 | err = snd_ctl_add(codec->card, | ||
281 | snd_soc_cnew(&uda1380_snd_controls[i], codec, NULL)); | ||
282 | if (err < 0) | ||
283 | return err; | ||
284 | } | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | /* Input mux */ | 274 | /* Input mux */ |
290 | static const struct snd_kcontrol_new uda1380_input_mux_control = | 275 | static const struct snd_kcontrol_new uda1380_input_mux_control = |
291 | SOC_DAPM_ENUM("Route", uda1380_input_sel_enum); | 276 | SOC_DAPM_ENUM("Route", uda1380_input_sel_enum); |
@@ -371,7 +356,7 @@ static int uda1380_add_widgets(struct snd_soc_codec *codec) | |||
371 | return 0; | 356 | return 0; |
372 | } | 357 | } |
373 | 358 | ||
374 | static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai, | 359 | static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai, |
375 | unsigned int fmt) | 360 | unsigned int fmt) |
376 | { | 361 | { |
377 | struct snd_soc_codec *codec = codec_dai->codec; | 362 | struct snd_soc_codec *codec = codec_dai->codec; |
@@ -381,16 +366,70 @@ static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
381 | iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); | 366 | iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); |
382 | iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK); | 367 | iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK); |
383 | 368 | ||
384 | /* FIXME: how to select I2S for DATAO and MSB for DATAI correctly? */ | ||
385 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 369 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
386 | case SND_SOC_DAIFMT_I2S: | 370 | case SND_SOC_DAIFMT_I2S: |
387 | iface |= R01_SFORI_I2S | R01_SFORO_I2S; | 371 | iface |= R01_SFORI_I2S | R01_SFORO_I2S; |
388 | break; | 372 | break; |
389 | case SND_SOC_DAIFMT_LSB: | 373 | case SND_SOC_DAIFMT_LSB: |
390 | iface |= R01_SFORI_LSB16 | R01_SFORO_I2S; | 374 | iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16; |
391 | break; | 375 | break; |
392 | case SND_SOC_DAIFMT_MSB: | 376 | case SND_SOC_DAIFMT_MSB: |
393 | iface |= R01_SFORI_MSB | R01_SFORO_I2S; | 377 | iface |= R01_SFORI_MSB | R01_SFORO_MSB; |
378 | } | ||
379 | |||
380 | if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) | ||
381 | iface |= R01_SIM; | ||
382 | |||
383 | uda1380_write(codec, UDA1380_IFACE, iface); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai, | ||
389 | unsigned int fmt) | ||
390 | { | ||
391 | struct snd_soc_codec *codec = codec_dai->codec; | ||
392 | int iface; | ||
393 | |||
394 | /* set up DAI based upon fmt */ | ||
395 | iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); | ||
396 | iface &= ~R01_SFORI_MASK; | ||
397 | |||
398 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
399 | case SND_SOC_DAIFMT_I2S: | ||
400 | iface |= R01_SFORI_I2S; | ||
401 | break; | ||
402 | case SND_SOC_DAIFMT_LSB: | ||
403 | iface |= R01_SFORI_LSB16; | ||
404 | break; | ||
405 | case SND_SOC_DAIFMT_MSB: | ||
406 | iface |= R01_SFORI_MSB; | ||
407 | } | ||
408 | |||
409 | uda1380_write(codec, UDA1380_IFACE, iface); | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai, | ||
415 | unsigned int fmt) | ||
416 | { | ||
417 | struct snd_soc_codec *codec = codec_dai->codec; | ||
418 | int iface; | ||
419 | |||
420 | /* set up DAI based upon fmt */ | ||
421 | iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); | ||
422 | iface &= ~(R01_SIM | R01_SFORO_MASK); | ||
423 | |||
424 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
425 | case SND_SOC_DAIFMT_I2S: | ||
426 | iface |= R01_SFORO_I2S; | ||
427 | break; | ||
428 | case SND_SOC_DAIFMT_LSB: | ||
429 | iface |= R01_SFORO_LSB16; | ||
430 | break; | ||
431 | case SND_SOC_DAIFMT_MSB: | ||
432 | iface |= R01_SFORO_MSB; | ||
394 | } | 433 | } |
395 | 434 | ||
396 | if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) | 435 | if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) |
@@ -412,7 +451,7 @@ static int uda1380_pcm_prepare(struct snd_pcm_substream *substream, | |||
412 | { | 451 | { |
413 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 452 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
414 | struct snd_soc_device *socdev = rtd->socdev; | 453 | struct snd_soc_device *socdev = rtd->socdev; |
415 | struct snd_soc_codec *codec = socdev->codec; | 454 | struct snd_soc_codec *codec = socdev->card->codec; |
416 | int reg, reg_start, reg_end, clk; | 455 | int reg, reg_start, reg_end, clk; |
417 | 456 | ||
418 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 457 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
@@ -433,8 +472,8 @@ static int uda1380_pcm_prepare(struct snd_pcm_substream *substream, | |||
433 | uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg)); | 472 | uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg)); |
434 | } | 473 | } |
435 | 474 | ||
436 | /* FIXME enable DAC_CLK */ | 475 | /* FIXME restore DAC_CLK */ |
437 | uda1380_write(codec, UDA1380_CLK, clk | R00_DAC_CLK); | 476 | uda1380_write(codec, UDA1380_CLK, clk); |
438 | 477 | ||
439 | return 0; | 478 | return 0; |
440 | } | 479 | } |
@@ -445,7 +484,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, | |||
445 | { | 484 | { |
446 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 485 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
447 | struct snd_soc_device *socdev = rtd->socdev; | 486 | struct snd_soc_device *socdev = rtd->socdev; |
448 | struct snd_soc_codec *codec = socdev->codec; | 487 | struct snd_soc_codec *codec = socdev->card->codec; |
449 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); | 488 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); |
450 | 489 | ||
451 | /* set WSPLL power and divider if running from this clock */ | 490 | /* set WSPLL power and divider if running from this clock */ |
@@ -484,7 +523,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, | |||
484 | { | 523 | { |
485 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 524 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
486 | struct snd_soc_device *socdev = rtd->socdev; | 525 | struct snd_soc_device *socdev = rtd->socdev; |
487 | struct snd_soc_codec *codec = socdev->codec; | 526 | struct snd_soc_codec *codec = socdev->card->codec; |
488 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); | 527 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); |
489 | 528 | ||
490 | /* shut down WSPLL power if running from this clock */ | 529 | /* shut down WSPLL power if running from this clock */ |
@@ -564,7 +603,7 @@ struct snd_soc_dai uda1380_dai[] = { | |||
564 | .shutdown = uda1380_pcm_shutdown, | 603 | .shutdown = uda1380_pcm_shutdown, |
565 | .prepare = uda1380_pcm_prepare, | 604 | .prepare = uda1380_pcm_prepare, |
566 | .digital_mute = uda1380_mute, | 605 | .digital_mute = uda1380_mute, |
567 | .set_fmt = uda1380_set_dai_fmt, | 606 | .set_fmt = uda1380_set_dai_fmt_both, |
568 | }, | 607 | }, |
569 | }, | 608 | }, |
570 | { /* playback only - dual interface */ | 609 | { /* playback only - dual interface */ |
@@ -581,7 +620,7 @@ struct snd_soc_dai uda1380_dai[] = { | |||
581 | .shutdown = uda1380_pcm_shutdown, | 620 | .shutdown = uda1380_pcm_shutdown, |
582 | .prepare = uda1380_pcm_prepare, | 621 | .prepare = uda1380_pcm_prepare, |
583 | .digital_mute = uda1380_mute, | 622 | .digital_mute = uda1380_mute, |
584 | .set_fmt = uda1380_set_dai_fmt, | 623 | .set_fmt = uda1380_set_dai_fmt_playback, |
585 | }, | 624 | }, |
586 | }, | 625 | }, |
587 | { /* capture only - dual interface*/ | 626 | { /* capture only - dual interface*/ |
@@ -597,7 +636,7 @@ struct snd_soc_dai uda1380_dai[] = { | |||
597 | .hw_params = uda1380_pcm_hw_params, | 636 | .hw_params = uda1380_pcm_hw_params, |
598 | .shutdown = uda1380_pcm_shutdown, | 637 | .shutdown = uda1380_pcm_shutdown, |
599 | .prepare = uda1380_pcm_prepare, | 638 | .prepare = uda1380_pcm_prepare, |
600 | .set_fmt = uda1380_set_dai_fmt, | 639 | .set_fmt = uda1380_set_dai_fmt_capture, |
601 | }, | 640 | }, |
602 | }, | 641 | }, |
603 | }; | 642 | }; |
@@ -606,7 +645,7 @@ EXPORT_SYMBOL_GPL(uda1380_dai); | |||
606 | static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) | 645 | static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) |
607 | { | 646 | { |
608 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 647 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
609 | struct snd_soc_codec *codec = socdev->codec; | 648 | struct snd_soc_codec *codec = socdev->card->codec; |
610 | 649 | ||
611 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); | 650 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); |
612 | return 0; | 651 | return 0; |
@@ -615,7 +654,7 @@ static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) | |||
615 | static int uda1380_resume(struct platform_device *pdev) | 654 | static int uda1380_resume(struct platform_device *pdev) |
616 | { | 655 | { |
617 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 656 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
618 | struct snd_soc_codec *codec = socdev->codec; | 657 | struct snd_soc_codec *codec = socdev->card->codec; |
619 | int i; | 658 | int i; |
620 | u8 data[2]; | 659 | u8 data[2]; |
621 | u16 *cache = codec->reg_cache; | 660 | u16 *cache = codec->reg_cache; |
@@ -637,7 +676,7 @@ static int uda1380_resume(struct platform_device *pdev) | |||
637 | */ | 676 | */ |
638 | static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) | 677 | static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) |
639 | { | 678 | { |
640 | struct snd_soc_codec *codec = socdev->codec; | 679 | struct snd_soc_codec *codec = socdev->card->codec; |
641 | int ret = 0; | 680 | int ret = 0; |
642 | 681 | ||
643 | codec->name = "UDA1380"; | 682 | codec->name = "UDA1380"; |
@@ -675,7 +714,8 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) | |||
675 | } | 714 | } |
676 | 715 | ||
677 | /* uda1380 init */ | 716 | /* uda1380 init */ |
678 | uda1380_add_controls(codec); | 717 | snd_soc_add_controls(codec, uda1380_snd_controls, |
718 | ARRAY_SIZE(uda1380_snd_controls)); | ||
679 | uda1380_add_widgets(codec); | 719 | uda1380_add_widgets(codec); |
680 | ret = snd_soc_init_card(socdev); | 720 | ret = snd_soc_init_card(socdev); |
681 | if (ret < 0) { | 721 | if (ret < 0) { |
@@ -702,7 +742,7 @@ static int uda1380_i2c_probe(struct i2c_client *i2c, | |||
702 | { | 742 | { |
703 | struct snd_soc_device *socdev = uda1380_socdev; | 743 | struct snd_soc_device *socdev = uda1380_socdev; |
704 | struct uda1380_setup_data *setup = socdev->codec_data; | 744 | struct uda1380_setup_data *setup = socdev->codec_data; |
705 | struct snd_soc_codec *codec = socdev->codec; | 745 | struct snd_soc_codec *codec = socdev->card->codec; |
706 | int ret; | 746 | int ret; |
707 | 747 | ||
708 | i2c_set_clientdata(i2c, codec); | 748 | i2c_set_clientdata(i2c, codec); |
@@ -793,7 +833,7 @@ static int uda1380_probe(struct platform_device *pdev) | |||
793 | if (codec == NULL) | 833 | if (codec == NULL) |
794 | return -ENOMEM; | 834 | return -ENOMEM; |
795 | 835 | ||
796 | socdev->codec = codec; | 836 | socdev->card->codec = codec; |
797 | mutex_init(&codec->mutex); | 837 | mutex_init(&codec->mutex); |
798 | INIT_LIST_HEAD(&codec->dapm_widgets); | 838 | INIT_LIST_HEAD(&codec->dapm_widgets); |
799 | INIT_LIST_HEAD(&codec->dapm_paths); | 839 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -817,7 +857,7 @@ static int uda1380_probe(struct platform_device *pdev) | |||
817 | static int uda1380_remove(struct platform_device *pdev) | 857 | static int uda1380_remove(struct platform_device *pdev) |
818 | { | 858 | { |
819 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 859 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
820 | struct snd_soc_codec *codec = socdev->codec; | 860 | struct snd_soc_codec *codec = socdev->card->codec; |
821 | 861 | ||
822 | if (codec->control_data) | 862 | if (codec->control_data) |
823 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); | 863 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 35d99750c383..d3562788d42b 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -51,10 +51,17 @@ struct wm8350_output { | |||
51 | u16 mute; | 51 | u16 mute; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | struct wm8350_jack_data { | ||
55 | struct snd_soc_jack *jack; | ||
56 | int report; | ||
57 | }; | ||
58 | |||
54 | struct wm8350_data { | 59 | struct wm8350_data { |
55 | struct snd_soc_codec codec; | 60 | struct snd_soc_codec codec; |
56 | struct wm8350_output out1; | 61 | struct wm8350_output out1; |
57 | struct wm8350_output out2; | 62 | struct wm8350_output out2; |
63 | struct wm8350_jack_data hpl; | ||
64 | struct wm8350_jack_data hpr; | ||
58 | struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; | 65 | struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; |
59 | }; | 66 | }; |
60 | 67 | ||
@@ -775,21 +782,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
775 | {"Beep", NULL, "IN3R PGA"}, | 782 | {"Beep", NULL, "IN3R PGA"}, |
776 | }; | 783 | }; |
777 | 784 | ||
778 | static int wm8350_add_controls(struct snd_soc_codec *codec) | ||
779 | { | ||
780 | int err, i; | ||
781 | |||
782 | for (i = 0; i < ARRAY_SIZE(wm8350_snd_controls); i++) { | ||
783 | err = snd_ctl_add(codec->card, | ||
784 | snd_soc_cnew(&wm8350_snd_controls[i], | ||
785 | codec, NULL)); | ||
786 | if (err < 0) | ||
787 | return err; | ||
788 | } | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static int wm8350_add_widgets(struct snd_soc_codec *codec) | 785 | static int wm8350_add_widgets(struct snd_soc_codec *codec) |
794 | { | 786 | { |
795 | int ret; | 787 | int ret; |
@@ -1309,7 +1301,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, | |||
1309 | static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) | 1301 | static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) |
1310 | { | 1302 | { |
1311 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1303 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1312 | struct snd_soc_codec *codec = socdev->codec; | 1304 | struct snd_soc_codec *codec = socdev->card->codec; |
1313 | 1305 | ||
1314 | wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1306 | wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1315 | return 0; | 1307 | return 0; |
@@ -1318,7 +1310,7 @@ static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) | |||
1318 | static int wm8350_resume(struct platform_device *pdev) | 1310 | static int wm8350_resume(struct platform_device *pdev) |
1319 | { | 1311 | { |
1320 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1312 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1321 | struct snd_soc_codec *codec = socdev->codec; | 1313 | struct snd_soc_codec *codec = socdev->card->codec; |
1322 | 1314 | ||
1323 | wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1315 | wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1324 | 1316 | ||
@@ -1328,6 +1320,95 @@ static int wm8350_resume(struct platform_device *pdev) | |||
1328 | return 0; | 1320 | return 0; |
1329 | } | 1321 | } |
1330 | 1322 | ||
1323 | static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data) | ||
1324 | { | ||
1325 | struct wm8350_data *priv = data; | ||
1326 | u16 reg; | ||
1327 | int report; | ||
1328 | int mask; | ||
1329 | struct wm8350_jack_data *jack = NULL; | ||
1330 | |||
1331 | switch (irq) { | ||
1332 | case WM8350_IRQ_CODEC_JCK_DET_L: | ||
1333 | jack = &priv->hpl; | ||
1334 | mask = WM8350_JACK_L_LVL; | ||
1335 | break; | ||
1336 | |||
1337 | case WM8350_IRQ_CODEC_JCK_DET_R: | ||
1338 | jack = &priv->hpr; | ||
1339 | mask = WM8350_JACK_R_LVL; | ||
1340 | break; | ||
1341 | |||
1342 | default: | ||
1343 | BUG(); | ||
1344 | } | ||
1345 | |||
1346 | if (!jack->jack) { | ||
1347 | dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); | ||
1348 | return; | ||
1349 | } | ||
1350 | |||
1351 | /* Debounce */ | ||
1352 | msleep(200); | ||
1353 | |||
1354 | reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); | ||
1355 | if (reg & mask) | ||
1356 | report = jack->report; | ||
1357 | else | ||
1358 | report = 0; | ||
1359 | |||
1360 | snd_soc_jack_report(jack->jack, report, jack->report); | ||
1361 | } | ||
1362 | |||
1363 | /** | ||
1364 | * wm8350_hp_jack_detect - Enable headphone jack detection. | ||
1365 | * | ||
1366 | * @codec: WM8350 codec | ||
1367 | * @which: left or right jack detect signal | ||
1368 | * @jack: jack to report detection events on | ||
1369 | * @report: value to report | ||
1370 | * | ||
1371 | * Enables the headphone jack detection of the WM8350. | ||
1372 | */ | ||
1373 | int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, | ||
1374 | struct snd_soc_jack *jack, int report) | ||
1375 | { | ||
1376 | struct wm8350_data *priv = codec->private_data; | ||
1377 | struct wm8350 *wm8350 = codec->control_data; | ||
1378 | int irq; | ||
1379 | int ena; | ||
1380 | |||
1381 | switch (which) { | ||
1382 | case WM8350_JDL: | ||
1383 | priv->hpl.jack = jack; | ||
1384 | priv->hpl.report = report; | ||
1385 | irq = WM8350_IRQ_CODEC_JCK_DET_L; | ||
1386 | ena = WM8350_JDL_ENA; | ||
1387 | break; | ||
1388 | |||
1389 | case WM8350_JDR: | ||
1390 | priv->hpr.jack = jack; | ||
1391 | priv->hpr.report = report; | ||
1392 | irq = WM8350_IRQ_CODEC_JCK_DET_R; | ||
1393 | ena = WM8350_JDR_ENA; | ||
1394 | break; | ||
1395 | |||
1396 | default: | ||
1397 | return -EINVAL; | ||
1398 | } | ||
1399 | |||
1400 | wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); | ||
1401 | wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); | ||
1402 | |||
1403 | /* Sync status */ | ||
1404 | wm8350_hp_jack_handler(wm8350, irq, priv); | ||
1405 | |||
1406 | wm8350_unmask_irq(wm8350, irq); | ||
1407 | |||
1408 | return 0; | ||
1409 | } | ||
1410 | EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); | ||
1411 | |||
1331 | static struct snd_soc_codec *wm8350_codec; | 1412 | static struct snd_soc_codec *wm8350_codec; |
1332 | 1413 | ||
1333 | static int wm8350_probe(struct platform_device *pdev) | 1414 | static int wm8350_probe(struct platform_device *pdev) |
@@ -1342,8 +1423,8 @@ static int wm8350_probe(struct platform_device *pdev) | |||
1342 | 1423 | ||
1343 | BUG_ON(!wm8350_codec); | 1424 | BUG_ON(!wm8350_codec); |
1344 | 1425 | ||
1345 | socdev->codec = wm8350_codec; | 1426 | socdev->card->codec = wm8350_codec; |
1346 | codec = socdev->codec; | 1427 | codec = socdev->card->codec; |
1347 | wm8350 = codec->control_data; | 1428 | wm8350 = codec->control_data; |
1348 | priv = codec->private_data; | 1429 | priv = codec->private_data; |
1349 | 1430 | ||
@@ -1381,13 +1462,21 @@ static int wm8350_probe(struct platform_device *pdev) | |||
1381 | wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, | 1462 | wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, |
1382 | WM8350_OUT2_VU | WM8350_OUT2R_MUTE); | 1463 | WM8350_OUT2_VU | WM8350_OUT2R_MUTE); |
1383 | 1464 | ||
1465 | wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); | ||
1466 | wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); | ||
1467 | wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, | ||
1468 | wm8350_hp_jack_handler, priv); | ||
1469 | wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, | ||
1470 | wm8350_hp_jack_handler, priv); | ||
1471 | |||
1384 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 1472 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
1385 | if (ret < 0) { | 1473 | if (ret < 0) { |
1386 | dev_err(&pdev->dev, "failed to create pcms\n"); | 1474 | dev_err(&pdev->dev, "failed to create pcms\n"); |
1387 | return ret; | 1475 | return ret; |
1388 | } | 1476 | } |
1389 | 1477 | ||
1390 | wm8350_add_controls(codec); | 1478 | snd_soc_add_controls(codec, wm8350_snd_controls, |
1479 | ARRAY_SIZE(wm8350_snd_controls)); | ||
1391 | wm8350_add_widgets(codec); | 1480 | wm8350_add_widgets(codec); |
1392 | 1481 | ||
1393 | wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1482 | wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
@@ -1409,10 +1498,23 @@ card_err: | |||
1409 | static int wm8350_remove(struct platform_device *pdev) | 1498 | static int wm8350_remove(struct platform_device *pdev) |
1410 | { | 1499 | { |
1411 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1500 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1412 | struct snd_soc_codec *codec = socdev->codec; | 1501 | struct snd_soc_codec *codec = socdev->card->codec; |
1413 | struct wm8350 *wm8350 = codec->control_data; | 1502 | struct wm8350 *wm8350 = codec->control_data; |
1503 | struct wm8350_data *priv = codec->private_data; | ||
1414 | int ret; | 1504 | int ret; |
1415 | 1505 | ||
1506 | wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, | ||
1507 | WM8350_JDL_ENA | WM8350_JDR_ENA); | ||
1508 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); | ||
1509 | |||
1510 | wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); | ||
1511 | wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); | ||
1512 | wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); | ||
1513 | wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); | ||
1514 | |||
1515 | priv->hpl.jack = NULL; | ||
1516 | priv->hpr.jack = NULL; | ||
1517 | |||
1416 | /* cancel any work waiting to be queued. */ | 1518 | /* cancel any work waiting to be queued. */ |
1417 | ret = cancel_delayed_work(&codec->delayed_work); | 1519 | ret = cancel_delayed_work(&codec->delayed_work); |
1418 | 1520 | ||
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h index cc2887aa6c38..d11bd9288cf9 100644 --- a/sound/soc/codecs/wm8350.h +++ b/sound/soc/codecs/wm8350.h | |||
@@ -17,4 +17,12 @@ | |||
17 | extern struct snd_soc_dai wm8350_dai; | 17 | extern struct snd_soc_dai wm8350_dai; |
18 | extern struct snd_soc_codec_device soc_codec_dev_wm8350; | 18 | extern struct snd_soc_codec_device soc_codec_dev_wm8350; |
19 | 19 | ||
20 | enum wm8350_jack { | ||
21 | WM8350_JDL = 1, | ||
22 | WM8350_JDR = 2, | ||
23 | }; | ||
24 | |||
25 | int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, | ||
26 | struct snd_soc_jack *jack, int report); | ||
27 | |||
20 | #endif | 28 | #endif |
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 40f8238df717..f01078cfbd72 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -171,22 +171,6 @@ SOC_SINGLE("Capture Boost(+20dB)", WM8510_ADCBOOST, 8, 1, 0), | |||
171 | SOC_SINGLE("Mono Playback Switch", WM8510_MONOMIX, 6, 1, 1), | 171 | SOC_SINGLE("Mono Playback Switch", WM8510_MONOMIX, 6, 1, 1), |
172 | }; | 172 | }; |
173 | 173 | ||
174 | /* add non dapm controls */ | ||
175 | static int wm8510_add_controls(struct snd_soc_codec *codec) | ||
176 | { | ||
177 | int err, i; | ||
178 | |||
179 | for (i = 0; i < ARRAY_SIZE(wm8510_snd_controls); i++) { | ||
180 | err = snd_ctl_add(codec->card, | ||
181 | snd_soc_cnew(&wm8510_snd_controls[i], codec, | ||
182 | NULL)); | ||
183 | if (err < 0) | ||
184 | return err; | ||
185 | } | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | /* Speaker Output Mixer */ | 174 | /* Speaker Output Mixer */ |
191 | static const struct snd_kcontrol_new wm8510_speaker_mixer_controls[] = { | 175 | static const struct snd_kcontrol_new wm8510_speaker_mixer_controls[] = { |
192 | SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_SPKMIX, 1, 1, 0), | 176 | SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_SPKMIX, 1, 1, 0), |
@@ -468,7 +452,7 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream, | |||
468 | { | 452 | { |
469 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 453 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
470 | struct snd_soc_device *socdev = rtd->socdev; | 454 | struct snd_soc_device *socdev = rtd->socdev; |
471 | struct snd_soc_codec *codec = socdev->codec; | 455 | struct snd_soc_codec *codec = socdev->card->codec; |
472 | u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f; | 456 | u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f; |
473 | u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1; | 457 | u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1; |
474 | 458 | ||
@@ -597,7 +581,7 @@ EXPORT_SYMBOL_GPL(wm8510_dai); | |||
597 | static int wm8510_suspend(struct platform_device *pdev, pm_message_t state) | 581 | static int wm8510_suspend(struct platform_device *pdev, pm_message_t state) |
598 | { | 582 | { |
599 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 583 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
600 | struct snd_soc_codec *codec = socdev->codec; | 584 | struct snd_soc_codec *codec = socdev->card->codec; |
601 | 585 | ||
602 | wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); | 586 | wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); |
603 | return 0; | 587 | return 0; |
@@ -606,7 +590,7 @@ static int wm8510_suspend(struct platform_device *pdev, pm_message_t state) | |||
606 | static int wm8510_resume(struct platform_device *pdev) | 590 | static int wm8510_resume(struct platform_device *pdev) |
607 | { | 591 | { |
608 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 592 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
609 | struct snd_soc_codec *codec = socdev->codec; | 593 | struct snd_soc_codec *codec = socdev->card->codec; |
610 | int i; | 594 | int i; |
611 | u8 data[2]; | 595 | u8 data[2]; |
612 | u16 *cache = codec->reg_cache; | 596 | u16 *cache = codec->reg_cache; |
@@ -628,7 +612,7 @@ static int wm8510_resume(struct platform_device *pdev) | |||
628 | */ | 612 | */ |
629 | static int wm8510_init(struct snd_soc_device *socdev) | 613 | static int wm8510_init(struct snd_soc_device *socdev) |
630 | { | 614 | { |
631 | struct snd_soc_codec *codec = socdev->codec; | 615 | struct snd_soc_codec *codec = socdev->card->codec; |
632 | int ret = 0; | 616 | int ret = 0; |
633 | 617 | ||
634 | codec->name = "WM8510"; | 618 | codec->name = "WM8510"; |
@@ -656,7 +640,8 @@ static int wm8510_init(struct snd_soc_device *socdev) | |||
656 | /* power on device */ | 640 | /* power on device */ |
657 | codec->bias_level = SND_SOC_BIAS_OFF; | 641 | codec->bias_level = SND_SOC_BIAS_OFF; |
658 | wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 642 | wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
659 | wm8510_add_controls(codec); | 643 | snd_soc_add_controls(codec, wm8510_snd_controls, |
644 | ARRAY_SIZE(wm8510_snd_controls)); | ||
660 | wm8510_add_widgets(codec); | 645 | wm8510_add_widgets(codec); |
661 | ret = snd_soc_init_card(socdev); | 646 | ret = snd_soc_init_card(socdev); |
662 | if (ret < 0) { | 647 | if (ret < 0) { |
@@ -685,7 +670,7 @@ static int wm8510_i2c_probe(struct i2c_client *i2c, | |||
685 | const struct i2c_device_id *id) | 670 | const struct i2c_device_id *id) |
686 | { | 671 | { |
687 | struct snd_soc_device *socdev = wm8510_socdev; | 672 | struct snd_soc_device *socdev = wm8510_socdev; |
688 | struct snd_soc_codec *codec = socdev->codec; | 673 | struct snd_soc_codec *codec = socdev->card->codec; |
689 | int ret; | 674 | int ret; |
690 | 675 | ||
691 | i2c_set_clientdata(i2c, codec); | 676 | i2c_set_clientdata(i2c, codec); |
@@ -766,7 +751,7 @@ err_driver: | |||
766 | static int __devinit wm8510_spi_probe(struct spi_device *spi) | 751 | static int __devinit wm8510_spi_probe(struct spi_device *spi) |
767 | { | 752 | { |
768 | struct snd_soc_device *socdev = wm8510_socdev; | 753 | struct snd_soc_device *socdev = wm8510_socdev; |
769 | struct snd_soc_codec *codec = socdev->codec; | 754 | struct snd_soc_codec *codec = socdev->card->codec; |
770 | int ret; | 755 | int ret; |
771 | 756 | ||
772 | codec->control_data = spi; | 757 | codec->control_data = spi; |
@@ -832,7 +817,7 @@ static int wm8510_probe(struct platform_device *pdev) | |||
832 | if (codec == NULL) | 817 | if (codec == NULL) |
833 | return -ENOMEM; | 818 | return -ENOMEM; |
834 | 819 | ||
835 | socdev->codec = codec; | 820 | socdev->card->codec = codec; |
836 | mutex_init(&codec->mutex); | 821 | mutex_init(&codec->mutex); |
837 | INIT_LIST_HEAD(&codec->dapm_widgets); | 822 | INIT_LIST_HEAD(&codec->dapm_widgets); |
838 | INIT_LIST_HEAD(&codec->dapm_paths); | 823 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -862,7 +847,7 @@ static int wm8510_probe(struct platform_device *pdev) | |||
862 | static int wm8510_remove(struct platform_device *pdev) | 847 | static int wm8510_remove(struct platform_device *pdev) |
863 | { | 848 | { |
864 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 849 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
865 | struct snd_soc_codec *codec = socdev->codec; | 850 | struct snd_soc_codec *codec = socdev->card->codec; |
866 | 851 | ||
867 | if (codec->control_data) | 852 | if (codec->control_data) |
868 | wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); | 853 | wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index d004e5845298..d3c51ba5e6f9 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -200,7 +200,7 @@ static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec, | |||
200 | unsigned int reg) | 200 | unsigned int reg) |
201 | { | 201 | { |
202 | u16 *cache = codec->reg_cache; | 202 | u16 *cache = codec->reg_cache; |
203 | BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); | 203 | BUG_ON(reg >= ARRAY_SIZE(wm8580_reg)); |
204 | return cache[reg]; | 204 | return cache[reg]; |
205 | } | 205 | } |
206 | 206 | ||
@@ -223,7 +223,7 @@ static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg, | |||
223 | { | 223 | { |
224 | u8 data[2]; | 224 | u8 data[2]; |
225 | 225 | ||
226 | BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); | 226 | BUG_ON(reg >= ARRAY_SIZE(wm8580_reg)); |
227 | 227 | ||
228 | /* Registers are 9 bits wide */ | 228 | /* Registers are 9 bits wide */ |
229 | value &= 0x1ff; | 229 | value &= 0x1ff; |
@@ -330,20 +330,6 @@ SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0), | |||
330 | SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), | 330 | SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), |
331 | }; | 331 | }; |
332 | 332 | ||
333 | /* Add non-DAPM controls */ | ||
334 | static int wm8580_add_controls(struct snd_soc_codec *codec) | ||
335 | { | ||
336 | int err, i; | ||
337 | |||
338 | for (i = 0; i < ARRAY_SIZE(wm8580_snd_controls); i++) { | ||
339 | err = snd_ctl_add(codec->card, | ||
340 | snd_soc_cnew(&wm8580_snd_controls[i], | ||
341 | codec, NULL)); | ||
342 | if (err < 0) | ||
343 | return err; | ||
344 | } | ||
345 | return 0; | ||
346 | } | ||
347 | static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { | 333 | static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { |
348 | SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1), | 334 | SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1), |
349 | SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1), | 335 | SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1), |
@@ -553,7 +539,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, | |||
553 | { | 539 | { |
554 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 540 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
555 | struct snd_soc_device *socdev = rtd->socdev; | 541 | struct snd_soc_device *socdev = rtd->socdev; |
556 | struct snd_soc_codec *codec = socdev->codec; | 542 | struct snd_soc_codec *codec = socdev->card->codec; |
557 | u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id); | 543 | u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id); |
558 | 544 | ||
559 | paifb &= ~WM8580_AIF_LENGTH_MASK; | 545 | paifb &= ~WM8580_AIF_LENGTH_MASK; |
@@ -830,7 +816,7 @@ EXPORT_SYMBOL_GPL(wm8580_dai); | |||
830 | */ | 816 | */ |
831 | static int wm8580_init(struct snd_soc_device *socdev) | 817 | static int wm8580_init(struct snd_soc_device *socdev) |
832 | { | 818 | { |
833 | struct snd_soc_codec *codec = socdev->codec; | 819 | struct snd_soc_codec *codec = socdev->card->codec; |
834 | int ret = 0; | 820 | int ret = 0; |
835 | 821 | ||
836 | codec->name = "WM8580"; | 822 | codec->name = "WM8580"; |
@@ -866,7 +852,8 @@ static int wm8580_init(struct snd_soc_device *socdev) | |||
866 | goto pcm_err; | 852 | goto pcm_err; |
867 | } | 853 | } |
868 | 854 | ||
869 | wm8580_add_controls(codec); | 855 | snd_soc_add_controls(codec, wm8580_snd_controls, |
856 | ARRAY_SIZE(wm8580_snd_controls)); | ||
870 | wm8580_add_widgets(codec); | 857 | wm8580_add_widgets(codec); |
871 | 858 | ||
872 | ret = snd_soc_init_card(socdev); | 859 | ret = snd_soc_init_card(socdev); |
@@ -901,7 +888,7 @@ static int wm8580_i2c_probe(struct i2c_client *i2c, | |||
901 | const struct i2c_device_id *id) | 888 | const struct i2c_device_id *id) |
902 | { | 889 | { |
903 | struct snd_soc_device *socdev = wm8580_socdev; | 890 | struct snd_soc_device *socdev = wm8580_socdev; |
904 | struct snd_soc_codec *codec = socdev->codec; | 891 | struct snd_soc_codec *codec = socdev->card->codec; |
905 | int ret; | 892 | int ret; |
906 | 893 | ||
907 | i2c_set_clientdata(i2c, codec); | 894 | i2c_set_clientdata(i2c, codec); |
@@ -999,7 +986,7 @@ static int wm8580_probe(struct platform_device *pdev) | |||
999 | } | 986 | } |
1000 | 987 | ||
1001 | codec->private_data = wm8580; | 988 | codec->private_data = wm8580; |
1002 | socdev->codec = codec; | 989 | socdev->card->codec = codec; |
1003 | mutex_init(&codec->mutex); | 990 | mutex_init(&codec->mutex); |
1004 | INIT_LIST_HEAD(&codec->dapm_widgets); | 991 | INIT_LIST_HEAD(&codec->dapm_widgets); |
1005 | INIT_LIST_HEAD(&codec->dapm_paths); | 992 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -1020,7 +1007,7 @@ static int wm8580_probe(struct platform_device *pdev) | |||
1020 | static int wm8580_remove(struct platform_device *pdev) | 1007 | static int wm8580_remove(struct platform_device *pdev) |
1021 | { | 1008 | { |
1022 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1009 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1023 | struct snd_soc_codec *codec = socdev->codec; | 1010 | struct snd_soc_codec *codec = socdev->card->codec; |
1024 | 1011 | ||
1025 | if (codec->control_data) | 1012 | if (codec->control_data) |
1026 | wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1013 | wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 80b11983e137..f8363b308895 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c | |||
@@ -47,7 +47,7 @@ static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec, | |||
47 | unsigned int reg) | 47 | unsigned int reg) |
48 | { | 48 | { |
49 | u16 *cache = codec->reg_cache; | 49 | u16 *cache = codec->reg_cache; |
50 | BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults)); | 50 | BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults)); |
51 | return cache[reg]; | 51 | return cache[reg]; |
52 | } | 52 | } |
53 | 53 | ||
@@ -55,7 +55,7 @@ static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec, | |||
55 | u16 reg, unsigned int value) | 55 | u16 reg, unsigned int value) |
56 | { | 56 | { |
57 | u16 *cache = codec->reg_cache; | 57 | u16 *cache = codec->reg_cache; |
58 | BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults)); | 58 | BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults)); |
59 | cache[reg] = value; | 59 | cache[reg] = value; |
60 | } | 60 | } |
61 | 61 | ||
@@ -92,21 +92,6 @@ SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8728_DACLVOL, WM8728_DACRVOL, | |||
92 | SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0), | 92 | SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0), |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static int wm8728_add_controls(struct snd_soc_codec *codec) | ||
96 | { | ||
97 | int err, i; | ||
98 | |||
99 | for (i = 0; i < ARRAY_SIZE(wm8728_snd_controls); i++) { | ||
100 | err = snd_ctl_add(codec->card, | ||
101 | snd_soc_cnew(&wm8728_snd_controls[i], | ||
102 | codec, NULL)); | ||
103 | if (err < 0) | ||
104 | return err; | ||
105 | } | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* | 95 | /* |
111 | * DAPM controls. | 96 | * DAPM controls. |
112 | */ | 97 | */ |
@@ -152,7 +137,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream, | |||
152 | { | 137 | { |
153 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 138 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
154 | struct snd_soc_device *socdev = rtd->socdev; | 139 | struct snd_soc_device *socdev = rtd->socdev; |
155 | struct snd_soc_codec *codec = socdev->codec; | 140 | struct snd_soc_codec *codec = socdev->card->codec; |
156 | u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL); | 141 | u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL); |
157 | 142 | ||
158 | dac &= ~0x18; | 143 | dac &= ~0x18; |
@@ -279,7 +264,7 @@ EXPORT_SYMBOL_GPL(wm8728_dai); | |||
279 | static int wm8728_suspend(struct platform_device *pdev, pm_message_t state) | 264 | static int wm8728_suspend(struct platform_device *pdev, pm_message_t state) |
280 | { | 265 | { |
281 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 266 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
282 | struct snd_soc_codec *codec = socdev->codec; | 267 | struct snd_soc_codec *codec = socdev->card->codec; |
283 | 268 | ||
284 | wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); | 269 | wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); |
285 | 270 | ||
@@ -289,7 +274,7 @@ static int wm8728_suspend(struct platform_device *pdev, pm_message_t state) | |||
289 | static int wm8728_resume(struct platform_device *pdev) | 274 | static int wm8728_resume(struct platform_device *pdev) |
290 | { | 275 | { |
291 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 276 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
292 | struct snd_soc_codec *codec = socdev->codec; | 277 | struct snd_soc_codec *codec = socdev->card->codec; |
293 | 278 | ||
294 | wm8728_set_bias_level(codec, codec->suspend_bias_level); | 279 | wm8728_set_bias_level(codec, codec->suspend_bias_level); |
295 | 280 | ||
@@ -302,7 +287,7 @@ static int wm8728_resume(struct platform_device *pdev) | |||
302 | */ | 287 | */ |
303 | static int wm8728_init(struct snd_soc_device *socdev) | 288 | static int wm8728_init(struct snd_soc_device *socdev) |
304 | { | 289 | { |
305 | struct snd_soc_codec *codec = socdev->codec; | 290 | struct snd_soc_codec *codec = socdev->card->codec; |
306 | int ret = 0; | 291 | int ret = 0; |
307 | 292 | ||
308 | codec->name = "WM8728"; | 293 | codec->name = "WM8728"; |
@@ -330,7 +315,8 @@ static int wm8728_init(struct snd_soc_device *socdev) | |||
330 | /* power on device */ | 315 | /* power on device */ |
331 | wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 316 | wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
332 | 317 | ||
333 | wm8728_add_controls(codec); | 318 | snd_soc_add_controls(codec, wm8728_snd_controls, |
319 | ARRAY_SIZE(wm8728_snd_controls)); | ||
334 | wm8728_add_widgets(codec); | 320 | wm8728_add_widgets(codec); |
335 | ret = snd_soc_init_card(socdev); | 321 | ret = snd_soc_init_card(socdev); |
336 | if (ret < 0) { | 322 | if (ret < 0) { |
@@ -363,7 +349,7 @@ static int wm8728_i2c_probe(struct i2c_client *i2c, | |||
363 | const struct i2c_device_id *id) | 349 | const struct i2c_device_id *id) |
364 | { | 350 | { |
365 | struct snd_soc_device *socdev = wm8728_socdev; | 351 | struct snd_soc_device *socdev = wm8728_socdev; |
366 | struct snd_soc_codec *codec = socdev->codec; | 352 | struct snd_soc_codec *codec = socdev->card->codec; |
367 | int ret; | 353 | int ret; |
368 | 354 | ||
369 | i2c_set_clientdata(i2c, codec); | 355 | i2c_set_clientdata(i2c, codec); |
@@ -444,7 +430,7 @@ err_driver: | |||
444 | static int __devinit wm8728_spi_probe(struct spi_device *spi) | 430 | static int __devinit wm8728_spi_probe(struct spi_device *spi) |
445 | { | 431 | { |
446 | struct snd_soc_device *socdev = wm8728_socdev; | 432 | struct snd_soc_device *socdev = wm8728_socdev; |
447 | struct snd_soc_codec *codec = socdev->codec; | 433 | struct snd_soc_codec *codec = socdev->card->codec; |
448 | int ret; | 434 | int ret; |
449 | 435 | ||
450 | codec->control_data = spi; | 436 | codec->control_data = spi; |
@@ -508,7 +494,7 @@ static int wm8728_probe(struct platform_device *pdev) | |||
508 | if (codec == NULL) | 494 | if (codec == NULL) |
509 | return -ENOMEM; | 495 | return -ENOMEM; |
510 | 496 | ||
511 | socdev->codec = codec; | 497 | socdev->card->codec = codec; |
512 | mutex_init(&codec->mutex); | 498 | mutex_init(&codec->mutex); |
513 | INIT_LIST_HEAD(&codec->dapm_widgets); | 499 | INIT_LIST_HEAD(&codec->dapm_widgets); |
514 | INIT_LIST_HEAD(&codec->dapm_paths); | 500 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -541,7 +527,7 @@ static int wm8728_probe(struct platform_device *pdev) | |||
541 | static int wm8728_remove(struct platform_device *pdev) | 527 | static int wm8728_remove(struct platform_device *pdev) |
542 | { | 528 | { |
543 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 529 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
544 | struct snd_soc_codec *codec = socdev->codec; | 530 | struct snd_soc_codec *codec = socdev->card->codec; |
545 | 531 | ||
546 | if (codec->control_data) | 532 | if (codec->control_data) |
547 | wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); | 533 | wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index c444b9f2701e..0150fe53a65d 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -129,22 +129,6 @@ SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), | |||
129 | SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), | 129 | SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), |
130 | }; | 130 | }; |
131 | 131 | ||
132 | /* add non dapm controls */ | ||
133 | static int wm8731_add_controls(struct snd_soc_codec *codec) | ||
134 | { | ||
135 | int err, i; | ||
136 | |||
137 | for (i = 0; i < ARRAY_SIZE(wm8731_snd_controls); i++) { | ||
138 | err = snd_ctl_add(codec->card, | ||
139 | snd_soc_cnew(&wm8731_snd_controls[i], | ||
140 | codec, NULL)); | ||
141 | if (err < 0) | ||
142 | return err; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | /* Output Mixer */ | 132 | /* Output Mixer */ |
149 | static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { | 133 | static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { |
150 | SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), | 134 | SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), |
@@ -269,7 +253,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream, | |||
269 | { | 253 | { |
270 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 254 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
271 | struct snd_soc_device *socdev = rtd->socdev; | 255 | struct snd_soc_device *socdev = rtd->socdev; |
272 | struct snd_soc_codec *codec = socdev->codec; | 256 | struct snd_soc_codec *codec = socdev->card->codec; |
273 | struct wm8731_priv *wm8731 = codec->private_data; | 257 | struct wm8731_priv *wm8731 = codec->private_data; |
274 | u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3; | 258 | u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3; |
275 | int i = get_coeff(wm8731->sysclk, params_rate(params)); | 259 | int i = get_coeff(wm8731->sysclk, params_rate(params)); |
@@ -299,7 +283,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, | |||
299 | { | 283 | { |
300 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 284 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
301 | struct snd_soc_device *socdev = rtd->socdev; | 285 | struct snd_soc_device *socdev = rtd->socdev; |
302 | struct snd_soc_codec *codec = socdev->codec; | 286 | struct snd_soc_codec *codec = socdev->card->codec; |
303 | 287 | ||
304 | /* set active */ | 288 | /* set active */ |
305 | wm8731_write(codec, WM8731_ACTIVE, 0x0001); | 289 | wm8731_write(codec, WM8731_ACTIVE, 0x0001); |
@@ -312,7 +296,7 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream, | |||
312 | { | 296 | { |
313 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 297 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
314 | struct snd_soc_device *socdev = rtd->socdev; | 298 | struct snd_soc_device *socdev = rtd->socdev; |
315 | struct snd_soc_codec *codec = socdev->codec; | 299 | struct snd_soc_codec *codec = socdev->card->codec; |
316 | 300 | ||
317 | /* deactivate */ | 301 | /* deactivate */ |
318 | if (!codec->active) { | 302 | if (!codec->active) { |
@@ -474,7 +458,7 @@ EXPORT_SYMBOL_GPL(wm8731_dai); | |||
474 | static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) | 458 | static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) |
475 | { | 459 | { |
476 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 460 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
477 | struct snd_soc_codec *codec = socdev->codec; | 461 | struct snd_soc_codec *codec = socdev->card->codec; |
478 | 462 | ||
479 | wm8731_write(codec, WM8731_ACTIVE, 0x0); | 463 | wm8731_write(codec, WM8731_ACTIVE, 0x0); |
480 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); | 464 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); |
@@ -484,7 +468,7 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) | |||
484 | static int wm8731_resume(struct platform_device *pdev) | 468 | static int wm8731_resume(struct platform_device *pdev) |
485 | { | 469 | { |
486 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 470 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
487 | struct snd_soc_codec *codec = socdev->codec; | 471 | struct snd_soc_codec *codec = socdev->card->codec; |
488 | int i; | 472 | int i; |
489 | u8 data[2]; | 473 | u8 data[2]; |
490 | u16 *cache = codec->reg_cache; | 474 | u16 *cache = codec->reg_cache; |
@@ -506,7 +490,7 @@ static int wm8731_resume(struct platform_device *pdev) | |||
506 | */ | 490 | */ |
507 | static int wm8731_init(struct snd_soc_device *socdev) | 491 | static int wm8731_init(struct snd_soc_device *socdev) |
508 | { | 492 | { |
509 | struct snd_soc_codec *codec = socdev->codec; | 493 | struct snd_soc_codec *codec = socdev->card->codec; |
510 | int reg, ret = 0; | 494 | int reg, ret = 0; |
511 | 495 | ||
512 | codec->name = "WM8731"; | 496 | codec->name = "WM8731"; |
@@ -543,7 +527,8 @@ static int wm8731_init(struct snd_soc_device *socdev) | |||
543 | reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); | 527 | reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); |
544 | wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100); | 528 | wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100); |
545 | 529 | ||
546 | wm8731_add_controls(codec); | 530 | snd_soc_add_controls(codec, wm8731_snd_controls, |
531 | ARRAY_SIZE(wm8731_snd_controls)); | ||
547 | wm8731_add_widgets(codec); | 532 | wm8731_add_widgets(codec); |
548 | ret = snd_soc_init_card(socdev); | 533 | ret = snd_soc_init_card(socdev); |
549 | if (ret < 0) { | 534 | if (ret < 0) { |
@@ -576,7 +561,7 @@ static int wm8731_i2c_probe(struct i2c_client *i2c, | |||
576 | const struct i2c_device_id *id) | 561 | const struct i2c_device_id *id) |
577 | { | 562 | { |
578 | struct snd_soc_device *socdev = wm8731_socdev; | 563 | struct snd_soc_device *socdev = wm8731_socdev; |
579 | struct snd_soc_codec *codec = socdev->codec; | 564 | struct snd_soc_codec *codec = socdev->card->codec; |
580 | int ret; | 565 | int ret; |
581 | 566 | ||
582 | i2c_set_clientdata(i2c, codec); | 567 | i2c_set_clientdata(i2c, codec); |
@@ -657,7 +642,7 @@ err_driver: | |||
657 | static int __devinit wm8731_spi_probe(struct spi_device *spi) | 642 | static int __devinit wm8731_spi_probe(struct spi_device *spi) |
658 | { | 643 | { |
659 | struct snd_soc_device *socdev = wm8731_socdev; | 644 | struct snd_soc_device *socdev = wm8731_socdev; |
660 | struct snd_soc_codec *codec = socdev->codec; | 645 | struct snd_soc_codec *codec = socdev->card->codec; |
661 | int ret; | 646 | int ret; |
662 | 647 | ||
663 | codec->control_data = spi; | 648 | codec->control_data = spi; |
@@ -731,7 +716,7 @@ static int wm8731_probe(struct platform_device *pdev) | |||
731 | } | 716 | } |
732 | 717 | ||
733 | codec->private_data = wm8731; | 718 | codec->private_data = wm8731; |
734 | socdev->codec = codec; | 719 | socdev->card->codec = codec; |
735 | mutex_init(&codec->mutex); | 720 | mutex_init(&codec->mutex); |
736 | INIT_LIST_HEAD(&codec->dapm_widgets); | 721 | INIT_LIST_HEAD(&codec->dapm_widgets); |
737 | INIT_LIST_HEAD(&codec->dapm_paths); | 722 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -765,7 +750,7 @@ static int wm8731_probe(struct platform_device *pdev) | |||
765 | static int wm8731_remove(struct platform_device *pdev) | 750 | static int wm8731_remove(struct platform_device *pdev) |
766 | { | 751 | { |
767 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 752 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
768 | struct snd_soc_codec *codec = socdev->codec; | 753 | struct snd_soc_codec *codec = socdev->card->codec; |
769 | 754 | ||
770 | if (codec->control_data) | 755 | if (codec->control_data) |
771 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); | 756 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 5997fa68e0d5..96afb86addc6 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -231,21 +231,6 @@ SOC_SINGLE("Mono Playback Volume", WM8750_MOUTV, 0, 127, 0), | |||
231 | 231 | ||
232 | }; | 232 | }; |
233 | 233 | ||
234 | /* add non dapm controls */ | ||
235 | static int wm8750_add_controls(struct snd_soc_codec *codec) | ||
236 | { | ||
237 | int err, i; | ||
238 | |||
239 | for (i = 0; i < ARRAY_SIZE(wm8750_snd_controls); i++) { | ||
240 | err = snd_ctl_add(codec->card, | ||
241 | snd_soc_cnew(&wm8750_snd_controls[i], | ||
242 | codec, NULL)); | ||
243 | if (err < 0) | ||
244 | return err; | ||
245 | } | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | /* | 234 | /* |
250 | * DAPM Controls | 235 | * DAPM Controls |
251 | */ | 236 | */ |
@@ -619,7 +604,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, | |||
619 | { | 604 | { |
620 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 605 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
621 | struct snd_soc_device *socdev = rtd->socdev; | 606 | struct snd_soc_device *socdev = rtd->socdev; |
622 | struct snd_soc_codec *codec = socdev->codec; | 607 | struct snd_soc_codec *codec = socdev->card->codec; |
623 | struct wm8750_priv *wm8750 = codec->private_data; | 608 | struct wm8750_priv *wm8750 = codec->private_data; |
624 | u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; | 609 | u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; |
625 | u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; | 610 | u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; |
@@ -727,7 +712,7 @@ static void wm8750_work(struct work_struct *work) | |||
727 | static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) | 712 | static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) |
728 | { | 713 | { |
729 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 714 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
730 | struct snd_soc_codec *codec = socdev->codec; | 715 | struct snd_soc_codec *codec = socdev->card->codec; |
731 | 716 | ||
732 | wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); | 717 | wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); |
733 | return 0; | 718 | return 0; |
@@ -736,7 +721,7 @@ static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) | |||
736 | static int wm8750_resume(struct platform_device *pdev) | 721 | static int wm8750_resume(struct platform_device *pdev) |
737 | { | 722 | { |
738 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 723 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
739 | struct snd_soc_codec *codec = socdev->codec; | 724 | struct snd_soc_codec *codec = socdev->card->codec; |
740 | int i; | 725 | int i; |
741 | u8 data[2]; | 726 | u8 data[2]; |
742 | u16 *cache = codec->reg_cache; | 727 | u16 *cache = codec->reg_cache; |
@@ -769,7 +754,7 @@ static int wm8750_resume(struct platform_device *pdev) | |||
769 | */ | 754 | */ |
770 | static int wm8750_init(struct snd_soc_device *socdev) | 755 | static int wm8750_init(struct snd_soc_device *socdev) |
771 | { | 756 | { |
772 | struct snd_soc_codec *codec = socdev->codec; | 757 | struct snd_soc_codec *codec = socdev->card->codec; |
773 | int reg, ret = 0; | 758 | int reg, ret = 0; |
774 | 759 | ||
775 | codec->name = "WM8750"; | 760 | codec->name = "WM8750"; |
@@ -816,7 +801,8 @@ static int wm8750_init(struct snd_soc_device *socdev) | |||
816 | reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); | 801 | reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); |
817 | wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); | 802 | wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); |
818 | 803 | ||
819 | wm8750_add_controls(codec); | 804 | snd_soc_add_controls(codec, wm8750_snd_controls, |
805 | ARRAY_SIZE(wm8750_snd_controls)); | ||
820 | wm8750_add_widgets(codec); | 806 | wm8750_add_widgets(codec); |
821 | ret = snd_soc_init_card(socdev); | 807 | ret = snd_soc_init_card(socdev); |
822 | if (ret < 0) { | 808 | if (ret < 0) { |
@@ -850,7 +836,7 @@ static int wm8750_i2c_probe(struct i2c_client *i2c, | |||
850 | const struct i2c_device_id *id) | 836 | const struct i2c_device_id *id) |
851 | { | 837 | { |
852 | struct snd_soc_device *socdev = wm8750_socdev; | 838 | struct snd_soc_device *socdev = wm8750_socdev; |
853 | struct snd_soc_codec *codec = socdev->codec; | 839 | struct snd_soc_codec *codec = socdev->card->codec; |
854 | int ret; | 840 | int ret; |
855 | 841 | ||
856 | i2c_set_clientdata(i2c, codec); | 842 | i2c_set_clientdata(i2c, codec); |
@@ -931,7 +917,7 @@ err_driver: | |||
931 | static int __devinit wm8750_spi_probe(struct spi_device *spi) | 917 | static int __devinit wm8750_spi_probe(struct spi_device *spi) |
932 | { | 918 | { |
933 | struct snd_soc_device *socdev = wm8750_socdev; | 919 | struct snd_soc_device *socdev = wm8750_socdev; |
934 | struct snd_soc_codec *codec = socdev->codec; | 920 | struct snd_soc_codec *codec = socdev->card->codec; |
935 | int ret; | 921 | int ret; |
936 | 922 | ||
937 | codec->control_data = spi; | 923 | codec->control_data = spi; |
@@ -1003,7 +989,7 @@ static int wm8750_probe(struct platform_device *pdev) | |||
1003 | } | 989 | } |
1004 | 990 | ||
1005 | codec->private_data = wm8750; | 991 | codec->private_data = wm8750; |
1006 | socdev->codec = codec; | 992 | socdev->card->codec = codec; |
1007 | mutex_init(&codec->mutex); | 993 | mutex_init(&codec->mutex); |
1008 | INIT_LIST_HEAD(&codec->dapm_widgets); | 994 | INIT_LIST_HEAD(&codec->dapm_widgets); |
1009 | INIT_LIST_HEAD(&codec->dapm_paths); | 995 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -1057,7 +1043,7 @@ static int run_delayed_work(struct delayed_work *dwork) | |||
1057 | static int wm8750_remove(struct platform_device *pdev) | 1043 | static int wm8750_remove(struct platform_device *pdev) |
1058 | { | 1044 | { |
1059 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1045 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1060 | struct snd_soc_codec *codec = socdev->codec; | 1046 | struct snd_soc_codec *codec = socdev->card->codec; |
1061 | 1047 | ||
1062 | if (codec->control_data) | 1048 | if (codec->control_data) |
1063 | wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1049 | wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 77620ab98756..6f9e6beabb14 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -97,7 +97,7 @@ static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec, | |||
97 | unsigned int reg) | 97 | unsigned int reg) |
98 | { | 98 | { |
99 | u16 *cache = codec->reg_cache; | 99 | u16 *cache = codec->reg_cache; |
100 | if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1)) | 100 | if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1)) |
101 | return -1; | 101 | return -1; |
102 | return cache[reg - 1]; | 102 | return cache[reg - 1]; |
103 | } | 103 | } |
@@ -109,7 +109,7 @@ static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec, | |||
109 | unsigned int reg, unsigned int value) | 109 | unsigned int reg, unsigned int value) |
110 | { | 110 | { |
111 | u16 *cache = codec->reg_cache; | 111 | u16 *cache = codec->reg_cache; |
112 | if (reg < 1 || reg > 0x3f) | 112 | if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1)) |
113 | return; | 113 | return; |
114 | cache[reg - 1] = value; | 114 | cache[reg - 1] = value; |
115 | } | 115 | } |
@@ -339,21 +339,6 @@ SOC_ENUM("ADC Data Select", wm8753_enum[27]), | |||
339 | SOC_ENUM("ROUT2 Phase", wm8753_enum[28]), | 339 | SOC_ENUM("ROUT2 Phase", wm8753_enum[28]), |
340 | }; | 340 | }; |
341 | 341 | ||
342 | /* add non dapm controls */ | ||
343 | static int wm8753_add_controls(struct snd_soc_codec *codec) | ||
344 | { | ||
345 | int err, i; | ||
346 | |||
347 | for (i = 0; i < ARRAY_SIZE(wm8753_snd_controls); i++) { | ||
348 | err = snd_ctl_add(codec->card, | ||
349 | snd_soc_cnew(&wm8753_snd_controls[i], | ||
350 | codec, NULL)); | ||
351 | if (err < 0) | ||
352 | return err; | ||
353 | } | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | /* | 342 | /* |
358 | * _DAPM_ Controls | 343 | * _DAPM_ Controls |
359 | */ | 344 | */ |
@@ -927,7 +912,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, | |||
927 | { | 912 | { |
928 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 913 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
929 | struct snd_soc_device *socdev = rtd->socdev; | 914 | struct snd_soc_device *socdev = rtd->socdev; |
930 | struct snd_soc_codec *codec = socdev->codec; | 915 | struct snd_soc_codec *codec = socdev->card->codec; |
931 | struct wm8753_priv *wm8753 = codec->private_data; | 916 | struct wm8753_priv *wm8753 = codec->private_data; |
932 | u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; | 917 | u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; |
933 | u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; | 918 | u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; |
@@ -1161,7 +1146,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, | |||
1161 | { | 1146 | { |
1162 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1147 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1163 | struct snd_soc_device *socdev = rtd->socdev; | 1148 | struct snd_soc_device *socdev = rtd->socdev; |
1164 | struct snd_soc_codec *codec = socdev->codec; | 1149 | struct snd_soc_codec *codec = socdev->card->codec; |
1165 | struct wm8753_priv *wm8753 = codec->private_data; | 1150 | struct wm8753_priv *wm8753 = codec->private_data; |
1166 | u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; | 1151 | u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; |
1167 | u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; | 1152 | u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; |
@@ -1505,7 +1490,7 @@ static void wm8753_work(struct work_struct *work) | |||
1505 | static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) | 1490 | static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) |
1506 | { | 1491 | { |
1507 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1492 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1508 | struct snd_soc_codec *codec = socdev->codec; | 1493 | struct snd_soc_codec *codec = socdev->card->codec; |
1509 | 1494 | ||
1510 | /* we only need to suspend if we are a valid card */ | 1495 | /* we only need to suspend if we are a valid card */ |
1511 | if (!codec->card) | 1496 | if (!codec->card) |
@@ -1518,7 +1503,7 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) | |||
1518 | static int wm8753_resume(struct platform_device *pdev) | 1503 | static int wm8753_resume(struct platform_device *pdev) |
1519 | { | 1504 | { |
1520 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1505 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1521 | struct snd_soc_codec *codec = socdev->codec; | 1506 | struct snd_soc_codec *codec = socdev->card->codec; |
1522 | int i; | 1507 | int i; |
1523 | u8 data[2]; | 1508 | u8 data[2]; |
1524 | u16 *cache = codec->reg_cache; | 1509 | u16 *cache = codec->reg_cache; |
@@ -1555,7 +1540,7 @@ static int wm8753_resume(struct platform_device *pdev) | |||
1555 | */ | 1540 | */ |
1556 | static int wm8753_init(struct snd_soc_device *socdev) | 1541 | static int wm8753_init(struct snd_soc_device *socdev) |
1557 | { | 1542 | { |
1558 | struct snd_soc_codec *codec = socdev->codec; | 1543 | struct snd_soc_codec *codec = socdev->card->codec; |
1559 | int reg, ret = 0; | 1544 | int reg, ret = 0; |
1560 | 1545 | ||
1561 | codec->name = "WM8753"; | 1546 | codec->name = "WM8753"; |
@@ -1610,7 +1595,8 @@ static int wm8753_init(struct snd_soc_device *socdev) | |||
1610 | reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); | 1595 | reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); |
1611 | wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); | 1596 | wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); |
1612 | 1597 | ||
1613 | wm8753_add_controls(codec); | 1598 | snd_soc_add_controls(codec, wm8753_snd_controls, |
1599 | ARRAY_SIZE(wm8753_snd_controls)); | ||
1614 | wm8753_add_widgets(codec); | 1600 | wm8753_add_widgets(codec); |
1615 | ret = snd_soc_init_card(socdev); | 1601 | ret = snd_soc_init_card(socdev); |
1616 | if (ret < 0) { | 1602 | if (ret < 0) { |
@@ -1645,7 +1631,7 @@ static int wm8753_i2c_probe(struct i2c_client *i2c, | |||
1645 | const struct i2c_device_id *id) | 1631 | const struct i2c_device_id *id) |
1646 | { | 1632 | { |
1647 | struct snd_soc_device *socdev = wm8753_socdev; | 1633 | struct snd_soc_device *socdev = wm8753_socdev; |
1648 | struct snd_soc_codec *codec = socdev->codec; | 1634 | struct snd_soc_codec *codec = socdev->card->codec; |
1649 | int ret; | 1635 | int ret; |
1650 | 1636 | ||
1651 | i2c_set_clientdata(i2c, codec); | 1637 | i2c_set_clientdata(i2c, codec); |
@@ -1726,7 +1712,7 @@ err_driver: | |||
1726 | static int __devinit wm8753_spi_probe(struct spi_device *spi) | 1712 | static int __devinit wm8753_spi_probe(struct spi_device *spi) |
1727 | { | 1713 | { |
1728 | struct snd_soc_device *socdev = wm8753_socdev; | 1714 | struct snd_soc_device *socdev = wm8753_socdev; |
1729 | struct snd_soc_codec *codec = socdev->codec; | 1715 | struct snd_soc_codec *codec = socdev->card->codec; |
1730 | int ret; | 1716 | int ret; |
1731 | 1717 | ||
1732 | codec->control_data = spi; | 1718 | codec->control_data = spi; |
@@ -1801,7 +1787,7 @@ static int wm8753_probe(struct platform_device *pdev) | |||
1801 | } | 1787 | } |
1802 | 1788 | ||
1803 | codec->private_data = wm8753; | 1789 | codec->private_data = wm8753; |
1804 | socdev->codec = codec; | 1790 | socdev->card->codec = codec; |
1805 | mutex_init(&codec->mutex); | 1791 | mutex_init(&codec->mutex); |
1806 | INIT_LIST_HEAD(&codec->dapm_widgets); | 1792 | INIT_LIST_HEAD(&codec->dapm_widgets); |
1807 | INIT_LIST_HEAD(&codec->dapm_paths); | 1793 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -1853,7 +1839,7 @@ static int run_delayed_work(struct delayed_work *dwork) | |||
1853 | static int wm8753_remove(struct platform_device *pdev) | 1839 | static int wm8753_remove(struct platform_device *pdev) |
1854 | { | 1840 | { |
1855 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1841 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1856 | struct snd_soc_codec *codec = socdev->codec; | 1842 | struct snd_soc_codec *codec = socdev->card->codec; |
1857 | 1843 | ||
1858 | if (codec->control_data) | 1844 | if (codec->control_data) |
1859 | wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1845 | wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 6767de10ded0..85c0f1bc6766 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -517,22 +517,6 @@ SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1, | |||
517 | 517 | ||
518 | }; | 518 | }; |
519 | 519 | ||
520 | /* add non dapm controls */ | ||
521 | static int wm8900_add_controls(struct snd_soc_codec *codec) | ||
522 | { | ||
523 | int err, i; | ||
524 | |||
525 | for (i = 0; i < ARRAY_SIZE(wm8900_snd_controls); i++) { | ||
526 | err = snd_ctl_add(codec->card, | ||
527 | snd_soc_cnew(&wm8900_snd_controls[i], | ||
528 | codec, NULL)); | ||
529 | if (err < 0) | ||
530 | return err; | ||
531 | } | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static const struct snd_kcontrol_new wm8900_dapm_loutput2_control = | 520 | static const struct snd_kcontrol_new wm8900_dapm_loutput2_control = |
537 | SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0); | 521 | SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0); |
538 | 522 | ||
@@ -736,7 +720,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream, | |||
736 | { | 720 | { |
737 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 721 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
738 | struct snd_soc_device *socdev = rtd->socdev; | 722 | struct snd_soc_device *socdev = rtd->socdev; |
739 | struct snd_soc_codec *codec = socdev->codec; | 723 | struct snd_soc_codec *codec = socdev->card->codec; |
740 | u16 reg; | 724 | u16 reg; |
741 | 725 | ||
742 | reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60; | 726 | reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60; |
@@ -1226,7 +1210,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, | |||
1226 | static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) | 1210 | static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) |
1227 | { | 1211 | { |
1228 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1212 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1229 | struct snd_soc_codec *codec = socdev->codec; | 1213 | struct snd_soc_codec *codec = socdev->card->codec; |
1230 | struct wm8900_priv *wm8900 = codec->private_data; | 1214 | struct wm8900_priv *wm8900 = codec->private_data; |
1231 | int fll_out = wm8900->fll_out; | 1215 | int fll_out = wm8900->fll_out; |
1232 | int fll_in = wm8900->fll_in; | 1216 | int fll_in = wm8900->fll_in; |
@@ -1250,7 +1234,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) | |||
1250 | static int wm8900_resume(struct platform_device *pdev) | 1234 | static int wm8900_resume(struct platform_device *pdev) |
1251 | { | 1235 | { |
1252 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1236 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1253 | struct snd_soc_codec *codec = socdev->codec; | 1237 | struct snd_soc_codec *codec = socdev->card->codec; |
1254 | struct wm8900_priv *wm8900 = codec->private_data; | 1238 | struct wm8900_priv *wm8900 = codec->private_data; |
1255 | u16 *cache; | 1239 | u16 *cache; |
1256 | int i, ret; | 1240 | int i, ret; |
@@ -1430,7 +1414,7 @@ static int wm8900_probe(struct platform_device *pdev) | |||
1430 | } | 1414 | } |
1431 | 1415 | ||
1432 | codec = wm8900_codec; | 1416 | codec = wm8900_codec; |
1433 | socdev->codec = codec; | 1417 | socdev->card->codec = codec; |
1434 | 1418 | ||
1435 | /* Register pcms */ | 1419 | /* Register pcms */ |
1436 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 1420 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
@@ -1439,7 +1423,8 @@ static int wm8900_probe(struct platform_device *pdev) | |||
1439 | goto pcm_err; | 1423 | goto pcm_err; |
1440 | } | 1424 | } |
1441 | 1425 | ||
1442 | wm8900_add_controls(codec); | 1426 | snd_soc_add_controls(codec, wm8900_snd_controls, |
1427 | ARRAY_SIZE(wm8900_snd_controls)); | ||
1443 | wm8900_add_widgets(codec); | 1428 | wm8900_add_widgets(codec); |
1444 | 1429 | ||
1445 | ret = snd_soc_init_card(socdev); | 1430 | ret = snd_soc_init_card(socdev); |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index bde74546db4a..d36b2b1edf19 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -744,21 +744,6 @@ SOC_DOUBLE_R_TLV("Speaker Volume", | |||
744 | 0, 63, 0, out_tlv), | 744 | 0, 63, 0, out_tlv), |
745 | }; | 745 | }; |
746 | 746 | ||
747 | static int wm8903_add_controls(struct snd_soc_codec *codec) | ||
748 | { | ||
749 | int err, i; | ||
750 | |||
751 | for (i = 0; i < ARRAY_SIZE(wm8903_snd_controls); i++) { | ||
752 | err = snd_ctl_add(codec->card, | ||
753 | snd_soc_cnew(&wm8903_snd_controls[i], | ||
754 | codec, NULL)); | ||
755 | if (err < 0) | ||
756 | return err; | ||
757 | } | ||
758 | |||
759 | return 0; | ||
760 | } | ||
761 | |||
762 | static const struct snd_kcontrol_new linput_mode_mux = | 747 | static const struct snd_kcontrol_new linput_mode_mux = |
763 | SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum); | 748 | SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum); |
764 | 749 | ||
@@ -1276,7 +1261,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream, | |||
1276 | { | 1261 | { |
1277 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1262 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1278 | struct snd_soc_device *socdev = rtd->socdev; | 1263 | struct snd_soc_device *socdev = rtd->socdev; |
1279 | struct snd_soc_codec *codec = socdev->codec; | 1264 | struct snd_soc_codec *codec = socdev->card->codec; |
1280 | struct wm8903_priv *wm8903 = codec->private_data; | 1265 | struct wm8903_priv *wm8903 = codec->private_data; |
1281 | struct i2c_client *i2c = codec->control_data; | 1266 | struct i2c_client *i2c = codec->control_data; |
1282 | struct snd_pcm_runtime *master_runtime; | 1267 | struct snd_pcm_runtime *master_runtime; |
@@ -1318,7 +1303,7 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream, | |||
1318 | { | 1303 | { |
1319 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1304 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1320 | struct snd_soc_device *socdev = rtd->socdev; | 1305 | struct snd_soc_device *socdev = rtd->socdev; |
1321 | struct snd_soc_codec *codec = socdev->codec; | 1306 | struct snd_soc_codec *codec = socdev->card->codec; |
1322 | struct wm8903_priv *wm8903 = codec->private_data; | 1307 | struct wm8903_priv *wm8903 = codec->private_data; |
1323 | 1308 | ||
1324 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1309 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -1338,7 +1323,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, | |||
1338 | { | 1323 | { |
1339 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1324 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1340 | struct snd_soc_device *socdev = rtd->socdev; | 1325 | struct snd_soc_device *socdev = rtd->socdev; |
1341 | struct snd_soc_codec *codec = socdev->codec; | 1326 | struct snd_soc_codec *codec = socdev->card->codec; |
1342 | struct wm8903_priv *wm8903 = codec->private_data; | 1327 | struct wm8903_priv *wm8903 = codec->private_data; |
1343 | struct i2c_client *i2c = codec->control_data; | 1328 | struct i2c_client *i2c = codec->control_data; |
1344 | int fs = params_rate(params); | 1329 | int fs = params_rate(params); |
@@ -1542,7 +1527,7 @@ EXPORT_SYMBOL_GPL(wm8903_dai); | |||
1542 | static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) | 1527 | static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) |
1543 | { | 1528 | { |
1544 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1529 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1545 | struct snd_soc_codec *codec = socdev->codec; | 1530 | struct snd_soc_codec *codec = socdev->card->codec; |
1546 | 1531 | ||
1547 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1532 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1548 | 1533 | ||
@@ -1552,7 +1537,7 @@ static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) | |||
1552 | static int wm8903_resume(struct platform_device *pdev) | 1537 | static int wm8903_resume(struct platform_device *pdev) |
1553 | { | 1538 | { |
1554 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1539 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1555 | struct snd_soc_codec *codec = socdev->codec; | 1540 | struct snd_soc_codec *codec = socdev->card->codec; |
1556 | struct i2c_client *i2c = codec->control_data; | 1541 | struct i2c_client *i2c = codec->control_data; |
1557 | int i; | 1542 | int i; |
1558 | u16 *reg_cache = codec->reg_cache; | 1543 | u16 *reg_cache = codec->reg_cache; |
@@ -1728,7 +1713,7 @@ static int wm8903_probe(struct platform_device *pdev) | |||
1728 | goto err; | 1713 | goto err; |
1729 | } | 1714 | } |
1730 | 1715 | ||
1731 | socdev->codec = wm8903_codec; | 1716 | socdev->card->codec = wm8903_codec; |
1732 | 1717 | ||
1733 | /* register pcms */ | 1718 | /* register pcms */ |
1734 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 1719 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
@@ -1737,8 +1722,9 @@ static int wm8903_probe(struct platform_device *pdev) | |||
1737 | goto err; | 1722 | goto err; |
1738 | } | 1723 | } |
1739 | 1724 | ||
1740 | wm8903_add_controls(socdev->codec); | 1725 | snd_soc_add_controls(socdev->card->codec, wm8903_snd_controls, |
1741 | wm8903_add_widgets(socdev->codec); | 1726 | ARRAY_SIZE(wm8903_snd_controls)); |
1727 | wm8903_add_widgets(socdev->card->codec); | ||
1742 | 1728 | ||
1743 | ret = snd_soc_init_card(socdev); | 1729 | ret = snd_soc_init_card(socdev); |
1744 | if (ret < 0) { | 1730 | if (ret < 0) { |
@@ -1759,7 +1745,7 @@ err: | |||
1759 | static int wm8903_remove(struct platform_device *pdev) | 1745 | static int wm8903_remove(struct platform_device *pdev) |
1760 | { | 1746 | { |
1761 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1747 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1762 | struct snd_soc_codec *codec = socdev->codec; | 1748 | struct snd_soc_codec *codec = socdev->card->codec; |
1763 | 1749 | ||
1764 | if (codec->control_data) | 1750 | if (codec->control_data) |
1765 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1751 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 88ead7f8dd98..24d4c905a011 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -195,21 +195,6 @@ static const struct snd_kcontrol_new wm8971_snd_controls[] = { | |||
195 | SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0), | 195 | SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0), |
196 | }; | 196 | }; |
197 | 197 | ||
198 | /* add non-DAPM controls */ | ||
199 | static int wm8971_add_controls(struct snd_soc_codec *codec) | ||
200 | { | ||
201 | int err, i; | ||
202 | |||
203 | for (i = 0; i < ARRAY_SIZE(wm8971_snd_controls); i++) { | ||
204 | err = snd_ctl_add(codec->card, | ||
205 | snd_soc_cnew(&wm8971_snd_controls[i], | ||
206 | codec, NULL)); | ||
207 | if (err < 0) | ||
208 | return err; | ||
209 | } | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /* | 198 | /* |
214 | * DAPM Controls | 199 | * DAPM Controls |
215 | */ | 200 | */ |
@@ -546,7 +531,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream, | |||
546 | { | 531 | { |
547 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 532 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
548 | struct snd_soc_device *socdev = rtd->socdev; | 533 | struct snd_soc_device *socdev = rtd->socdev; |
549 | struct snd_soc_codec *codec = socdev->codec; | 534 | struct snd_soc_codec *codec = socdev->card->codec; |
550 | struct wm8971_priv *wm8971 = codec->private_data; | 535 | struct wm8971_priv *wm8971 = codec->private_data; |
551 | u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3; | 536 | u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3; |
552 | u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0; | 537 | u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0; |
@@ -652,7 +637,7 @@ static void wm8971_work(struct work_struct *work) | |||
652 | static int wm8971_suspend(struct platform_device *pdev, pm_message_t state) | 637 | static int wm8971_suspend(struct platform_device *pdev, pm_message_t state) |
653 | { | 638 | { |
654 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 639 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
655 | struct snd_soc_codec *codec = socdev->codec; | 640 | struct snd_soc_codec *codec = socdev->card->codec; |
656 | 641 | ||
657 | wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); | 642 | wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); |
658 | return 0; | 643 | return 0; |
@@ -661,7 +646,7 @@ static int wm8971_suspend(struct platform_device *pdev, pm_message_t state) | |||
661 | static int wm8971_resume(struct platform_device *pdev) | 646 | static int wm8971_resume(struct platform_device *pdev) |
662 | { | 647 | { |
663 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 648 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
664 | struct snd_soc_codec *codec = socdev->codec; | 649 | struct snd_soc_codec *codec = socdev->card->codec; |
665 | int i; | 650 | int i; |
666 | u8 data[2]; | 651 | u8 data[2]; |
667 | u16 *cache = codec->reg_cache; | 652 | u16 *cache = codec->reg_cache; |
@@ -692,7 +677,7 @@ static int wm8971_resume(struct platform_device *pdev) | |||
692 | 677 | ||
693 | static int wm8971_init(struct snd_soc_device *socdev) | 678 | static int wm8971_init(struct snd_soc_device *socdev) |
694 | { | 679 | { |
695 | struct snd_soc_codec *codec = socdev->codec; | 680 | struct snd_soc_codec *codec = socdev->card->codec; |
696 | int reg, ret = 0; | 681 | int reg, ret = 0; |
697 | 682 | ||
698 | codec->name = "WM8971"; | 683 | codec->name = "WM8971"; |
@@ -745,7 +730,8 @@ static int wm8971_init(struct snd_soc_device *socdev) | |||
745 | reg = wm8971_read_reg_cache(codec, WM8971_RINVOL); | 730 | reg = wm8971_read_reg_cache(codec, WM8971_RINVOL); |
746 | wm8971_write(codec, WM8971_RINVOL, reg | 0x0100); | 731 | wm8971_write(codec, WM8971_RINVOL, reg | 0x0100); |
747 | 732 | ||
748 | wm8971_add_controls(codec); | 733 | snd_soc_add_controls(codec, wm8971_snd_controls, |
734 | ARRAY_SIZE(wm8971_snd_controls)); | ||
749 | wm8971_add_widgets(codec); | 735 | wm8971_add_widgets(codec); |
750 | ret = snd_soc_init_card(socdev); | 736 | ret = snd_soc_init_card(socdev); |
751 | if (ret < 0) { | 737 | if (ret < 0) { |
@@ -772,7 +758,7 @@ static int wm8971_i2c_probe(struct i2c_client *i2c, | |||
772 | const struct i2c_device_id *id) | 758 | const struct i2c_device_id *id) |
773 | { | 759 | { |
774 | struct snd_soc_device *socdev = wm8971_socdev; | 760 | struct snd_soc_device *socdev = wm8971_socdev; |
775 | struct snd_soc_codec *codec = socdev->codec; | 761 | struct snd_soc_codec *codec = socdev->card->codec; |
776 | int ret; | 762 | int ret; |
777 | 763 | ||
778 | i2c_set_clientdata(i2c, codec); | 764 | i2c_set_clientdata(i2c, codec); |
@@ -873,7 +859,7 @@ static int wm8971_probe(struct platform_device *pdev) | |||
873 | } | 859 | } |
874 | 860 | ||
875 | codec->private_data = wm8971; | 861 | codec->private_data = wm8971; |
876 | socdev->codec = codec; | 862 | socdev->card->codec = codec; |
877 | mutex_init(&codec->mutex); | 863 | mutex_init(&codec->mutex); |
878 | INIT_LIST_HEAD(&codec->dapm_widgets); | 864 | INIT_LIST_HEAD(&codec->dapm_widgets); |
879 | INIT_LIST_HEAD(&codec->dapm_paths); | 865 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -908,7 +894,7 @@ static int wm8971_probe(struct platform_device *pdev) | |||
908 | static int wm8971_remove(struct platform_device *pdev) | 894 | static int wm8971_remove(struct platform_device *pdev) |
909 | { | 895 | { |
910 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 896 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
911 | struct snd_soc_codec *codec = socdev->codec; | 897 | struct snd_soc_codec *codec = socdev->card->codec; |
912 | 898 | ||
913 | if (codec->control_data) | 899 | if (codec->control_data) |
914 | wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); | 900 | wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index a5731faa150c..1a38421f7594 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -115,7 +115,7 @@ static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec, | |||
115 | unsigned int reg) | 115 | unsigned int reg) |
116 | { | 116 | { |
117 | u16 *cache = codec->reg_cache; | 117 | u16 *cache = codec->reg_cache; |
118 | BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1); | 118 | BUG_ON(reg >= ARRAY_SIZE(wm8990_reg)); |
119 | return cache[reg]; | 119 | return cache[reg]; |
120 | } | 120 | } |
121 | 121 | ||
@@ -128,7 +128,7 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec, | |||
128 | u16 *cache = codec->reg_cache; | 128 | u16 *cache = codec->reg_cache; |
129 | 129 | ||
130 | /* Reset register and reserved registers are uncached */ | 130 | /* Reset register and reserved registers are uncached */ |
131 | if (reg == 0 || reg > ARRAY_SIZE(wm8990_reg) - 1) | 131 | if (reg == 0 || reg >= ARRAY_SIZE(wm8990_reg)) |
132 | return; | 132 | return; |
133 | 133 | ||
134 | cache[reg] = value; | 134 | cache[reg] = value; |
@@ -418,21 +418,6 @@ SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME, | |||
418 | 418 | ||
419 | }; | 419 | }; |
420 | 420 | ||
421 | /* add non dapm controls */ | ||
422 | static int wm8990_add_controls(struct snd_soc_codec *codec) | ||
423 | { | ||
424 | int err, i; | ||
425 | |||
426 | for (i = 0; i < ARRAY_SIZE(wm8990_snd_controls); i++) { | ||
427 | err = snd_ctl_add(codec->card, | ||
428 | snd_soc_cnew(&wm8990_snd_controls[i], codec, | ||
429 | NULL)); | ||
430 | if (err < 0) | ||
431 | return err; | ||
432 | } | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | /* | 421 | /* |
437 | * _DAPM_ Controls | 422 | * _DAPM_ Controls |
438 | */ | 423 | */ |
@@ -1178,7 +1163,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream, | |||
1178 | { | 1163 | { |
1179 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1164 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1180 | struct snd_soc_device *socdev = rtd->socdev; | 1165 | struct snd_soc_device *socdev = rtd->socdev; |
1181 | struct snd_soc_codec *codec = socdev->codec; | 1166 | struct snd_soc_codec *codec = socdev->card->codec; |
1182 | u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1); | 1167 | u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1); |
1183 | 1168 | ||
1184 | audio1 &= ~WM8990_AIF_WL_MASK; | 1169 | audio1 &= ~WM8990_AIF_WL_MASK; |
@@ -1377,7 +1362,7 @@ EXPORT_SYMBOL_GPL(wm8990_dai); | |||
1377 | static int wm8990_suspend(struct platform_device *pdev, pm_message_t state) | 1362 | static int wm8990_suspend(struct platform_device *pdev, pm_message_t state) |
1378 | { | 1363 | { |
1379 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1364 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1380 | struct snd_soc_codec *codec = socdev->codec; | 1365 | struct snd_soc_codec *codec = socdev->card->codec; |
1381 | 1366 | ||
1382 | /* we only need to suspend if we are a valid card */ | 1367 | /* we only need to suspend if we are a valid card */ |
1383 | if (!codec->card) | 1368 | if (!codec->card) |
@@ -1390,7 +1375,7 @@ static int wm8990_suspend(struct platform_device *pdev, pm_message_t state) | |||
1390 | static int wm8990_resume(struct platform_device *pdev) | 1375 | static int wm8990_resume(struct platform_device *pdev) |
1391 | { | 1376 | { |
1392 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1377 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1393 | struct snd_soc_codec *codec = socdev->codec; | 1378 | struct snd_soc_codec *codec = socdev->card->codec; |
1394 | int i; | 1379 | int i; |
1395 | u8 data[2]; | 1380 | u8 data[2]; |
1396 | u16 *cache = codec->reg_cache; | 1381 | u16 *cache = codec->reg_cache; |
@@ -1418,7 +1403,7 @@ static int wm8990_resume(struct platform_device *pdev) | |||
1418 | */ | 1403 | */ |
1419 | static int wm8990_init(struct snd_soc_device *socdev) | 1404 | static int wm8990_init(struct snd_soc_device *socdev) |
1420 | { | 1405 | { |
1421 | struct snd_soc_codec *codec = socdev->codec; | 1406 | struct snd_soc_codec *codec = socdev->card->codec; |
1422 | u16 reg; | 1407 | u16 reg; |
1423 | int ret = 0; | 1408 | int ret = 0; |
1424 | 1409 | ||
@@ -1461,7 +1446,8 @@ static int wm8990_init(struct snd_soc_device *socdev) | |||
1461 | wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1446 | wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1462 | wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1447 | wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1463 | 1448 | ||
1464 | wm8990_add_controls(codec); | 1449 | snd_soc_add_controls(codec, wm8990_snd_controls, |
1450 | ARRAY_SIZE(wm8990_snd_controls)); | ||
1465 | wm8990_add_widgets(codec); | 1451 | wm8990_add_widgets(codec); |
1466 | ret = snd_soc_init_card(socdev); | 1452 | ret = snd_soc_init_card(socdev); |
1467 | if (ret < 0) { | 1453 | if (ret < 0) { |
@@ -1495,7 +1481,7 @@ static int wm8990_i2c_probe(struct i2c_client *i2c, | |||
1495 | const struct i2c_device_id *id) | 1481 | const struct i2c_device_id *id) |
1496 | { | 1482 | { |
1497 | struct snd_soc_device *socdev = wm8990_socdev; | 1483 | struct snd_soc_device *socdev = wm8990_socdev; |
1498 | struct snd_soc_codec *codec = socdev->codec; | 1484 | struct snd_soc_codec *codec = socdev->card->codec; |
1499 | int ret; | 1485 | int ret; |
1500 | 1486 | ||
1501 | i2c_set_clientdata(i2c, codec); | 1487 | i2c_set_clientdata(i2c, codec); |
@@ -1594,7 +1580,7 @@ static int wm8990_probe(struct platform_device *pdev) | |||
1594 | } | 1580 | } |
1595 | 1581 | ||
1596 | codec->private_data = wm8990; | 1582 | codec->private_data = wm8990; |
1597 | socdev->codec = codec; | 1583 | socdev->card->codec = codec; |
1598 | mutex_init(&codec->mutex); | 1584 | mutex_init(&codec->mutex); |
1599 | INIT_LIST_HEAD(&codec->dapm_widgets); | 1585 | INIT_LIST_HEAD(&codec->dapm_widgets); |
1600 | INIT_LIST_HEAD(&codec->dapm_paths); | 1586 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -1620,7 +1606,7 @@ static int wm8990_probe(struct platform_device *pdev) | |||
1620 | static int wm8990_remove(struct platform_device *pdev) | 1606 | static int wm8990_remove(struct platform_device *pdev) |
1621 | { | 1607 | { |
1622 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1608 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1623 | struct snd_soc_codec *codec = socdev->codec; | 1609 | struct snd_soc_codec *codec = socdev->card->codec; |
1624 | 1610 | ||
1625 | if (codec->control_data) | 1611 | if (codec->control_data) |
1626 | wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1612 | wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); |
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c new file mode 100644 index 000000000000..2e9e06b2daaf --- /dev/null +++ b/sound/soc/codecs/wm9705.c | |||
@@ -0,0 +1,413 @@ | |||
1 | /* | ||
2 | * wm9705.c -- ALSA Soc WM9705 codec support | ||
3 | * | ||
4 | * Copyright 2008 Ian Molton <spyro@f2s.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; Version 2 of the License only. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <sound/core.h> | ||
17 | #include <sound/pcm.h> | ||
18 | #include <sound/ac97_codec.h> | ||
19 | #include <sound/initval.h> | ||
20 | #include <sound/soc.h> | ||
21 | #include <sound/soc-dapm.h> | ||
22 | |||
23 | #include "wm9705.h" | ||
24 | |||
25 | /* | ||
26 | * WM9705 register cache | ||
27 | */ | ||
28 | static const u16 wm9705_reg[] = { | ||
29 | 0x6150, 0x8000, 0x8000, 0x8000, /* 0x0 */ | ||
30 | 0x0000, 0x8000, 0x8008, 0x8008, /* 0x8 */ | ||
31 | 0x8808, 0x8808, 0x8808, 0x8808, /* 0x10 */ | ||
32 | 0x8808, 0x0000, 0x8000, 0x0000, /* 0x18 */ | ||
33 | 0x0000, 0x0000, 0x0000, 0x000f, /* 0x20 */ | ||
34 | 0x0605, 0x0000, 0xbb80, 0x0000, /* 0x28 */ | ||
35 | 0x0000, 0xbb80, 0x0000, 0x0000, /* 0x30 */ | ||
36 | 0x0000, 0x2000, 0x0000, 0x0000, /* 0x38 */ | ||
37 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x40 */ | ||
38 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x48 */ | ||
39 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x50 */ | ||
40 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x58 */ | ||
41 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x60 */ | ||
42 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x68 */ | ||
43 | 0x0000, 0x0808, 0x0000, 0x0006, /* 0x70 */ | ||
44 | 0x0000, 0x0000, 0x574d, 0x4c05, /* 0x78 */ | ||
45 | }; | ||
46 | |||
47 | static const struct snd_kcontrol_new wm9705_snd_ac97_controls[] = { | ||
48 | SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), | ||
49 | SOC_SINGLE("Master Playback Switch", AC97_MASTER, 15, 1, 1), | ||
50 | SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), | ||
51 | SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1), | ||
52 | SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1), | ||
53 | SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1), | ||
54 | SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1), | ||
55 | SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1), | ||
56 | SOC_SINGLE("PCBeep Playback Volume", AC97_PC_BEEP, 1, 15, 1), | ||
57 | SOC_SINGLE("Phone Playback Volume", AC97_PHONE, 0, 31, 1), | ||
58 | SOC_DOUBLE("Line Playback Volume", AC97_LINE, 8, 0, 31, 1), | ||
59 | SOC_DOUBLE("CD Playback Volume", AC97_CD, 8, 0, 31, 1), | ||
60 | SOC_SINGLE("Mic Playback Volume", AC97_MIC, 0, 31, 1), | ||
61 | SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 6, 1, 0), | ||
62 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0), | ||
63 | SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1), | ||
64 | }; | ||
65 | |||
66 | static const char *wm9705_mic[] = {"Mic 1", "Mic 2"}; | ||
67 | static const char *wm9705_rec_sel[] = {"Mic", "CD", "NC", "NC", | ||
68 | "Line", "Stereo Mix", "Mono Mix", "Phone"}; | ||
69 | |||
70 | static const struct soc_enum wm9705_enum_mic = | ||
71 | SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, wm9705_mic); | ||
72 | static const struct soc_enum wm9705_enum_rec_l = | ||
73 | SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9705_rec_sel); | ||
74 | static const struct soc_enum wm9705_enum_rec_r = | ||
75 | SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9705_rec_sel); | ||
76 | |||
77 | /* Headphone Mixer */ | ||
78 | static const struct snd_kcontrol_new wm9705_hp_mixer_controls[] = { | ||
79 | SOC_DAPM_SINGLE("PCBeep Playback Switch", AC97_PC_BEEP, 15, 1, 1), | ||
80 | SOC_DAPM_SINGLE("CD Playback Switch", AC97_CD, 15, 1, 1), | ||
81 | SOC_DAPM_SINGLE("Mic Playback Switch", AC97_MIC, 15, 1, 1), | ||
82 | SOC_DAPM_SINGLE("Phone Playback Switch", AC97_PHONE, 15, 1, 1), | ||
83 | SOC_DAPM_SINGLE("Line Playback Switch", AC97_LINE, 15, 1, 1), | ||
84 | }; | ||
85 | |||
86 | /* Mic source */ | ||
87 | static const struct snd_kcontrol_new wm9705_mic_src_controls = | ||
88 | SOC_DAPM_ENUM("Route", wm9705_enum_mic); | ||
89 | |||
90 | /* Capture source */ | ||
91 | static const struct snd_kcontrol_new wm9705_capture_selectl_controls = | ||
92 | SOC_DAPM_ENUM("Route", wm9705_enum_rec_l); | ||
93 | static const struct snd_kcontrol_new wm9705_capture_selectr_controls = | ||
94 | SOC_DAPM_ENUM("Route", wm9705_enum_rec_r); | ||
95 | |||
96 | /* DAPM widgets */ | ||
97 | static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = { | ||
98 | SND_SOC_DAPM_MUX("Mic Source", SND_SOC_NOPM, 0, 0, | ||
99 | &wm9705_mic_src_controls), | ||
100 | SND_SOC_DAPM_MUX("Left Capture Source", SND_SOC_NOPM, 0, 0, | ||
101 | &wm9705_capture_selectl_controls), | ||
102 | SND_SOC_DAPM_MUX("Right Capture Source", SND_SOC_NOPM, 0, 0, | ||
103 | &wm9705_capture_selectr_controls), | ||
104 | SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", | ||
105 | SND_SOC_NOPM, 0, 0), | ||
106 | SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", | ||
107 | SND_SOC_NOPM, 0, 0), | ||
108 | SND_SOC_DAPM_MIXER_NAMED_CTL("HP Mixer", SND_SOC_NOPM, 0, 0, | ||
109 | &wm9705_hp_mixer_controls[0], | ||
110 | ARRAY_SIZE(wm9705_hp_mixer_controls)), | ||
111 | SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
112 | SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0), | ||
113 | SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0), | ||
114 | SND_SOC_DAPM_PGA("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
115 | SND_SOC_DAPM_PGA("Speaker PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
116 | SND_SOC_DAPM_PGA("Line PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
117 | SND_SOC_DAPM_PGA("Line out PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
118 | SND_SOC_DAPM_PGA("Mono PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
119 | SND_SOC_DAPM_PGA("Phone PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
120 | SND_SOC_DAPM_PGA("Mic PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
121 | SND_SOC_DAPM_PGA("PCBEEP PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
122 | SND_SOC_DAPM_PGA("CD PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
123 | SND_SOC_DAPM_PGA("ADC PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
124 | SND_SOC_DAPM_OUTPUT("HPOUTL"), | ||
125 | SND_SOC_DAPM_OUTPUT("HPOUTR"), | ||
126 | SND_SOC_DAPM_OUTPUT("LOUT"), | ||
127 | SND_SOC_DAPM_OUTPUT("ROUT"), | ||
128 | SND_SOC_DAPM_OUTPUT("MONOOUT"), | ||
129 | SND_SOC_DAPM_INPUT("PHONE"), | ||
130 | SND_SOC_DAPM_INPUT("LINEINL"), | ||
131 | SND_SOC_DAPM_INPUT("LINEINR"), | ||
132 | SND_SOC_DAPM_INPUT("CDINL"), | ||
133 | SND_SOC_DAPM_INPUT("CDINR"), | ||
134 | SND_SOC_DAPM_INPUT("PCBEEP"), | ||
135 | SND_SOC_DAPM_INPUT("MIC1"), | ||
136 | SND_SOC_DAPM_INPUT("MIC2"), | ||
137 | }; | ||
138 | |||
139 | /* Audio map | ||
140 | * WM9705 has no switches to disable the route from the inputs to the HP mixer | ||
141 | * so in order to prevent active inputs from forcing the audio outputs to be | ||
142 | * constantly enabled, we use the mutes on those inputs to simulate such | ||
143 | * controls. | ||
144 | */ | ||
145 | static const struct snd_soc_dapm_route audio_map[] = { | ||
146 | /* HP mixer */ | ||
147 | {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"}, | ||
148 | {"HP Mixer", "CD Playback Switch", "CD PGA"}, | ||
149 | {"HP Mixer", "Mic Playback Switch", "Mic PGA"}, | ||
150 | {"HP Mixer", "Phone Playback Switch", "Phone PGA"}, | ||
151 | {"HP Mixer", "Line Playback Switch", "Line PGA"}, | ||
152 | {"HP Mixer", NULL, "Left DAC"}, | ||
153 | {"HP Mixer", NULL, "Right DAC"}, | ||
154 | |||
155 | /* mono mixer */ | ||
156 | {"Mono Mixer", NULL, "HP Mixer"}, | ||
157 | |||
158 | /* outputs */ | ||
159 | {"Headphone PGA", NULL, "HP Mixer"}, | ||
160 | {"HPOUTL", NULL, "Headphone PGA"}, | ||
161 | {"HPOUTR", NULL, "Headphone PGA"}, | ||
162 | {"Line out PGA", NULL, "HP Mixer"}, | ||
163 | {"LOUT", NULL, "Line out PGA"}, | ||
164 | {"ROUT", NULL, "Line out PGA"}, | ||
165 | {"Mono PGA", NULL, "Mono Mixer"}, | ||
166 | {"MONOOUT", NULL, "Mono PGA"}, | ||
167 | |||
168 | /* inputs */ | ||
169 | {"CD PGA", NULL, "CDINL"}, | ||
170 | {"CD PGA", NULL, "CDINR"}, | ||
171 | {"Line PGA", NULL, "LINEINL"}, | ||
172 | {"Line PGA", NULL, "LINEINR"}, | ||
173 | {"Phone PGA", NULL, "PHONE"}, | ||
174 | {"Mic Source", "Mic 1", "MIC1"}, | ||
175 | {"Mic Source", "Mic 2", "MIC2"}, | ||
176 | {"Mic PGA", NULL, "Mic Source"}, | ||
177 | {"PCBEEP PGA", NULL, "PCBEEP"}, | ||
178 | |||
179 | /* Left capture selector */ | ||
180 | {"Left Capture Source", "Mic", "Mic Source"}, | ||
181 | {"Left Capture Source", "CD", "CDINL"}, | ||
182 | {"Left Capture Source", "Line", "LINEINL"}, | ||
183 | {"Left Capture Source", "Stereo Mix", "HP Mixer"}, | ||
184 | {"Left Capture Source", "Mono Mix", "HP Mixer"}, | ||
185 | {"Left Capture Source", "Phone", "PHONE"}, | ||
186 | |||
187 | /* Right capture source */ | ||
188 | {"Right Capture Source", "Mic", "Mic Source"}, | ||
189 | {"Right Capture Source", "CD", "CDINR"}, | ||
190 | {"Right Capture Source", "Line", "LINEINR"}, | ||
191 | {"Right Capture Source", "Stereo Mix", "HP Mixer"}, | ||
192 | {"Right Capture Source", "Mono Mix", "HP Mixer"}, | ||
193 | {"Right Capture Source", "Phone", "PHONE"}, | ||
194 | |||
195 | {"ADC PGA", NULL, "Left Capture Source"}, | ||
196 | {"ADC PGA", NULL, "Right Capture Source"}, | ||
197 | |||
198 | /* ADC's */ | ||
199 | {"Left ADC", NULL, "ADC PGA"}, | ||
200 | {"Right ADC", NULL, "ADC PGA"}, | ||
201 | }; | ||
202 | |||
203 | static int wm9705_add_widgets(struct snd_soc_codec *codec) | ||
204 | { | ||
205 | snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, | ||
206 | ARRAY_SIZE(wm9705_dapm_widgets)); | ||
207 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | ||
208 | snd_soc_dapm_new_widgets(codec); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /* We use a register cache to enhance read performance. */ | ||
214 | static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) | ||
215 | { | ||
216 | u16 *cache = codec->reg_cache; | ||
217 | |||
218 | switch (reg) { | ||
219 | case AC97_RESET: | ||
220 | case AC97_VENDOR_ID1: | ||
221 | case AC97_VENDOR_ID2: | ||
222 | return soc_ac97_ops.read(codec->ac97, reg); | ||
223 | default: | ||
224 | reg = reg >> 1; | ||
225 | |||
226 | if (reg >= (ARRAY_SIZE(wm9705_reg))) | ||
227 | return -EIO; | ||
228 | |||
229 | return cache[reg]; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, | ||
234 | unsigned int val) | ||
235 | { | ||
236 | u16 *cache = codec->reg_cache; | ||
237 | |||
238 | soc_ac97_ops.write(codec->ac97, reg, val); | ||
239 | reg = reg >> 1; | ||
240 | if (reg < (ARRAY_SIZE(wm9705_reg))) | ||
241 | cache[reg] = val; | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int ac97_prepare(struct snd_pcm_substream *substream, | ||
247 | struct snd_soc_dai *dai) | ||
248 | { | ||
249 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
250 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
251 | struct snd_soc_device *socdev = rtd->socdev; | ||
252 | struct snd_soc_codec *codec = socdev->card->codec; | ||
253 | int reg; | ||
254 | u16 vra; | ||
255 | |||
256 | vra = ac97_read(codec, AC97_EXTENDED_STATUS); | ||
257 | ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); | ||
258 | |||
259 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
260 | reg = AC97_PCM_FRONT_DAC_RATE; | ||
261 | else | ||
262 | reg = AC97_PCM_LR_ADC_RATE; | ||
263 | |||
264 | return ac97_write(codec, reg, runtime->rate); | ||
265 | } | ||
266 | |||
267 | #define WM9705_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \ | ||
268 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ | ||
269 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ | ||
270 | SNDRV_PCM_RATE_48000) | ||
271 | |||
272 | struct snd_soc_dai wm9705_dai[] = { | ||
273 | { | ||
274 | .name = "AC97 HiFi", | ||
275 | .ac97_control = 1, | ||
276 | .playback = { | ||
277 | .stream_name = "HiFi Playback", | ||
278 | .channels_min = 1, | ||
279 | .channels_max = 2, | ||
280 | .rates = WM9705_AC97_RATES, | ||
281 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
282 | }, | ||
283 | .capture = { | ||
284 | .stream_name = "HiFi Capture", | ||
285 | .channels_min = 1, | ||
286 | .channels_max = 2, | ||
287 | .rates = WM9705_AC97_RATES, | ||
288 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
289 | }, | ||
290 | .ops = { | ||
291 | .prepare = ac97_prepare, | ||
292 | }, | ||
293 | }, | ||
294 | { | ||
295 | .name = "AC97 Aux", | ||
296 | .playback = { | ||
297 | .stream_name = "Aux Playback", | ||
298 | .channels_min = 1, | ||
299 | .channels_max = 1, | ||
300 | .rates = WM9705_AC97_RATES, | ||
301 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
302 | }, | ||
303 | } | ||
304 | }; | ||
305 | EXPORT_SYMBOL_GPL(wm9705_dai); | ||
306 | |||
307 | static int wm9705_reset(struct snd_soc_codec *codec) | ||
308 | { | ||
309 | if (soc_ac97_ops.reset) { | ||
310 | soc_ac97_ops.reset(codec->ac97); | ||
311 | if (ac97_read(codec, 0) == wm9705_reg[0]) | ||
312 | return 0; /* Success */ | ||
313 | } | ||
314 | |||
315 | return -EIO; | ||
316 | } | ||
317 | |||
318 | static int wm9705_soc_probe(struct platform_device *pdev) | ||
319 | { | ||
320 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
321 | struct snd_soc_codec *codec; | ||
322 | int ret = 0; | ||
323 | |||
324 | printk(KERN_INFO "WM9705 SoC Audio Codec\n"); | ||
325 | |||
326 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), | ||
327 | GFP_KERNEL); | ||
328 | if (socdev->card->codec == NULL) | ||
329 | return -ENOMEM; | ||
330 | codec = socdev->card->codec; | ||
331 | mutex_init(&codec->mutex); | ||
332 | |||
333 | codec->reg_cache = kmemdup(wm9705_reg, sizeof(wm9705_reg), GFP_KERNEL); | ||
334 | if (codec->reg_cache == NULL) { | ||
335 | ret = -ENOMEM; | ||
336 | goto cache_err; | ||
337 | } | ||
338 | codec->reg_cache_size = sizeof(wm9705_reg); | ||
339 | codec->reg_cache_step = 2; | ||
340 | |||
341 | codec->name = "WM9705"; | ||
342 | codec->owner = THIS_MODULE; | ||
343 | codec->dai = wm9705_dai; | ||
344 | codec->num_dai = ARRAY_SIZE(wm9705_dai); | ||
345 | codec->write = ac97_write; | ||
346 | codec->read = ac97_read; | ||
347 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
348 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
349 | |||
350 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | ||
351 | if (ret < 0) { | ||
352 | printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); | ||
353 | goto codec_err; | ||
354 | } | ||
355 | |||
356 | /* register pcms */ | ||
357 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
358 | if (ret < 0) | ||
359 | goto pcm_err; | ||
360 | |||
361 | ret = wm9705_reset(codec); | ||
362 | if (ret) | ||
363 | goto reset_err; | ||
364 | |||
365 | snd_soc_add_controls(codec, wm9705_snd_ac97_controls, | ||
366 | ARRAY_SIZE(wm9705_snd_ac97_controls)); | ||
367 | wm9705_add_widgets(codec); | ||
368 | |||
369 | ret = snd_soc_init_card(socdev); | ||
370 | if (ret < 0) { | ||
371 | printk(KERN_ERR "wm9705: failed to register card\n"); | ||
372 | goto pcm_err; | ||
373 | } | ||
374 | |||
375 | return 0; | ||
376 | |||
377 | reset_err: | ||
378 | snd_soc_free_pcms(socdev); | ||
379 | pcm_err: | ||
380 | snd_soc_free_ac97_codec(codec); | ||
381 | codec_err: | ||
382 | kfree(codec->reg_cache); | ||
383 | cache_err: | ||
384 | kfree(socdev->card->codec); | ||
385 | socdev->card->codec = NULL; | ||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | static int wm9705_soc_remove(struct platform_device *pdev) | ||
390 | { | ||
391 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
392 | struct snd_soc_codec *codec = socdev->card->codec; | ||
393 | |||
394 | if (codec == NULL) | ||
395 | return 0; | ||
396 | |||
397 | snd_soc_dapm_free(socdev); | ||
398 | snd_soc_free_pcms(socdev); | ||
399 | snd_soc_free_ac97_codec(codec); | ||
400 | kfree(codec->reg_cache); | ||
401 | kfree(codec); | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | struct snd_soc_codec_device soc_codec_dev_wm9705 = { | ||
406 | .probe = wm9705_soc_probe, | ||
407 | .remove = wm9705_soc_remove, | ||
408 | }; | ||
409 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705); | ||
410 | |||
411 | MODULE_DESCRIPTION("ASoC WM9705 driver"); | ||
412 | MODULE_AUTHOR("Ian Molton"); | ||
413 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/wm9705.h b/sound/soc/codecs/wm9705.h new file mode 100644 index 000000000000..d380f110f9e2 --- /dev/null +++ b/sound/soc/codecs/wm9705.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * wm9705.h -- WM9705 Soc Audio driver | ||
3 | */ | ||
4 | |||
5 | #ifndef _WM9705_H | ||
6 | #define _WM9705_H | ||
7 | |||
8 | #define WM9705_DAI_AC97_HIFI 0 | ||
9 | #define WM9705_DAI_AC97_AUX 1 | ||
10 | |||
11 | extern struct snd_soc_dai wm9705_dai[2]; | ||
12 | extern struct snd_soc_codec_device soc_codec_dev_wm9705; | ||
13 | |||
14 | #endif | ||
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index af83d629078a..b3a8be77676e 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -154,21 +154,6 @@ SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), | |||
154 | SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), | 154 | SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), |
155 | }; | 155 | }; |
156 | 156 | ||
157 | /* add non dapm controls */ | ||
158 | static int wm9712_add_controls(struct snd_soc_codec *codec) | ||
159 | { | ||
160 | int err, i; | ||
161 | |||
162 | for (i = 0; i < ARRAY_SIZE(wm9712_snd_ac97_controls); i++) { | ||
163 | err = snd_ctl_add(codec->card, | ||
164 | snd_soc_cnew(&wm9712_snd_ac97_controls[i], | ||
165 | codec, NULL)); | ||
166 | if (err < 0) | ||
167 | return err; | ||
168 | } | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | /* We have to create a fake left and right HP mixers because | 157 | /* We have to create a fake left and right HP mixers because |
173 | * the codec only has a single control that is shared by both channels. | 158 | * the codec only has a single control that is shared by both channels. |
174 | * This makes it impossible to determine the audio path. | 159 | * This makes it impossible to determine the audio path. |
@@ -467,7 +452,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, | |||
467 | else { | 452 | else { |
468 | reg = reg >> 1; | 453 | reg = reg >> 1; |
469 | 454 | ||
470 | if (reg > (ARRAY_SIZE(wm9712_reg))) | 455 | if (reg >= (ARRAY_SIZE(wm9712_reg))) |
471 | return -EIO; | 456 | return -EIO; |
472 | 457 | ||
473 | return cache[reg]; | 458 | return cache[reg]; |
@@ -481,7 +466,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, | |||
481 | 466 | ||
482 | soc_ac97_ops.write(codec->ac97, reg, val); | 467 | soc_ac97_ops.write(codec->ac97, reg, val); |
483 | reg = reg >> 1; | 468 | reg = reg >> 1; |
484 | if (reg <= (ARRAY_SIZE(wm9712_reg))) | 469 | if (reg < (ARRAY_SIZE(wm9712_reg))) |
485 | cache[reg] = val; | 470 | cache[reg] = val; |
486 | 471 | ||
487 | return 0; | 472 | return 0; |
@@ -493,7 +478,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream, | |||
493 | struct snd_pcm_runtime *runtime = substream->runtime; | 478 | struct snd_pcm_runtime *runtime = substream->runtime; |
494 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 479 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
495 | struct snd_soc_device *socdev = rtd->socdev; | 480 | struct snd_soc_device *socdev = rtd->socdev; |
496 | struct snd_soc_codec *codec = socdev->codec; | 481 | struct snd_soc_codec *codec = socdev->card->codec; |
497 | int reg; | 482 | int reg; |
498 | u16 vra; | 483 | u16 vra; |
499 | 484 | ||
@@ -514,7 +499,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream, | |||
514 | struct snd_pcm_runtime *runtime = substream->runtime; | 499 | struct snd_pcm_runtime *runtime = substream->runtime; |
515 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 500 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
516 | struct snd_soc_device *socdev = rtd->socdev; | 501 | struct snd_soc_device *socdev = rtd->socdev; |
517 | struct snd_soc_codec *codec = socdev->codec; | 502 | struct snd_soc_codec *codec = socdev->card->codec; |
518 | u16 vra, xsle; | 503 | u16 vra, xsle; |
519 | 504 | ||
520 | vra = ac97_read(codec, AC97_EXTENDED_STATUS); | 505 | vra = ac97_read(codec, AC97_EXTENDED_STATUS); |
@@ -607,7 +592,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev, | |||
607 | pm_message_t state) | 592 | pm_message_t state) |
608 | { | 593 | { |
609 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 594 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
610 | struct snd_soc_codec *codec = socdev->codec; | 595 | struct snd_soc_codec *codec = socdev->card->codec; |
611 | 596 | ||
612 | wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); | 597 | wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); |
613 | return 0; | 598 | return 0; |
@@ -616,7 +601,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev, | |||
616 | static int wm9712_soc_resume(struct platform_device *pdev) | 601 | static int wm9712_soc_resume(struct platform_device *pdev) |
617 | { | 602 | { |
618 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 603 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
619 | struct snd_soc_codec *codec = socdev->codec; | 604 | struct snd_soc_codec *codec = socdev->card->codec; |
620 | int i, ret; | 605 | int i, ret; |
621 | u16 *cache = codec->reg_cache; | 606 | u16 *cache = codec->reg_cache; |
622 | 607 | ||
@@ -652,10 +637,11 @@ static int wm9712_soc_probe(struct platform_device *pdev) | |||
652 | 637 | ||
653 | printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); | 638 | printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); |
654 | 639 | ||
655 | socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 640 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), |
656 | if (socdev->codec == NULL) | 641 | GFP_KERNEL); |
642 | if (socdev->card->codec == NULL) | ||
657 | return -ENOMEM; | 643 | return -ENOMEM; |
658 | codec = socdev->codec; | 644 | codec = socdev->card->codec; |
659 | mutex_init(&codec->mutex); | 645 | mutex_init(&codec->mutex); |
660 | 646 | ||
661 | codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); | 647 | codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); |
@@ -698,7 +684,8 @@ static int wm9712_soc_probe(struct platform_device *pdev) | |||
698 | ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); | 684 | ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); |
699 | 685 | ||
700 | wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 686 | wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
701 | wm9712_add_controls(codec); | 687 | snd_soc_add_controls(codec, wm9712_snd_ac97_controls, |
688 | ARRAY_SIZE(wm9712_snd_ac97_controls)); | ||
702 | wm9712_add_widgets(codec); | 689 | wm9712_add_widgets(codec); |
703 | ret = snd_soc_init_card(socdev); | 690 | ret = snd_soc_init_card(socdev); |
704 | if (ret < 0) { | 691 | if (ret < 0) { |
@@ -718,15 +705,15 @@ codec_err: | |||
718 | kfree(codec->reg_cache); | 705 | kfree(codec->reg_cache); |
719 | 706 | ||
720 | cache_err: | 707 | cache_err: |
721 | kfree(socdev->codec); | 708 | kfree(socdev->card->codec); |
722 | socdev->codec = NULL; | 709 | socdev->card->codec = NULL; |
723 | return ret; | 710 | return ret; |
724 | } | 711 | } |
725 | 712 | ||
726 | static int wm9712_soc_remove(struct platform_device *pdev) | 713 | static int wm9712_soc_remove(struct platform_device *pdev) |
727 | { | 714 | { |
728 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 715 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
729 | struct snd_soc_codec *codec = socdev->codec; | 716 | struct snd_soc_codec *codec = socdev->card->codec; |
730 | 717 | ||
731 | if (codec == NULL) | 718 | if (codec == NULL) |
732 | return 0; | 719 | return 0; |
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index f3ca8aaf0139..54db9c524988 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | struct wm9713_priv { | 33 | struct wm9713_priv { |
34 | u32 pll_in; /* PLL input frequency */ | 34 | u32 pll_in; /* PLL input frequency */ |
35 | u32 pll_out; /* PLL output frequency */ | ||
36 | }; | 35 | }; |
37 | 36 | ||
38 | static unsigned int ac97_read(struct snd_soc_codec *codec, | 37 | static unsigned int ac97_read(struct snd_soc_codec *codec, |
@@ -190,21 +189,6 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), | |||
190 | SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), | 189 | SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), |
191 | }; | 190 | }; |
192 | 191 | ||
193 | /* add non dapm controls */ | ||
194 | static int wm9713_add_controls(struct snd_soc_codec *codec) | ||
195 | { | ||
196 | int err, i; | ||
197 | |||
198 | for (i = 0; i < ARRAY_SIZE(wm9713_snd_ac97_controls); i++) { | ||
199 | err = snd_ctl_add(codec->card, | ||
200 | snd_soc_cnew(&wm9713_snd_ac97_controls[i], | ||
201 | codec, NULL)); | ||
202 | if (err < 0) | ||
203 | return err; | ||
204 | } | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | /* We have to create a fake left and right HP mixers because | 192 | /* We have to create a fake left and right HP mixers because |
209 | * the codec only has a single control that is shared by both channels. | 193 | * the codec only has a single control that is shared by both channels. |
210 | * This makes it impossible to determine the audio path using the current | 194 | * This makes it impossible to determine the audio path using the current |
@@ -636,7 +620,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, | |||
636 | else { | 620 | else { |
637 | reg = reg >> 1; | 621 | reg = reg >> 1; |
638 | 622 | ||
639 | if (reg > (ARRAY_SIZE(wm9713_reg))) | 623 | if (reg >= (ARRAY_SIZE(wm9713_reg))) |
640 | return -EIO; | 624 | return -EIO; |
641 | 625 | ||
642 | return cache[reg]; | 626 | return cache[reg]; |
@@ -650,7 +634,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, | |||
650 | if (reg < 0x7c) | 634 | if (reg < 0x7c) |
651 | soc_ac97_ops.write(codec->ac97, reg, val); | 635 | soc_ac97_ops.write(codec->ac97, reg, val); |
652 | reg = reg >> 1; | 636 | reg = reg >> 1; |
653 | if (reg <= (ARRAY_SIZE(wm9713_reg))) | 637 | if (reg < (ARRAY_SIZE(wm9713_reg))) |
654 | cache[reg] = val; | 638 | cache[reg] = val; |
655 | 639 | ||
656 | return 0; | 640 | return 0; |
@@ -738,13 +722,13 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, | |||
738 | struct _pll_div pll_div; | 722 | struct _pll_div pll_div; |
739 | 723 | ||
740 | /* turn PLL off ? */ | 724 | /* turn PLL off ? */ |
741 | if (freq_in == 0 || freq_out == 0) { | 725 | if (freq_in == 0) { |
742 | /* disable PLL power and select ext source */ | 726 | /* disable PLL power and select ext source */ |
743 | reg = ac97_read(codec, AC97_HANDSET_RATE); | 727 | reg = ac97_read(codec, AC97_HANDSET_RATE); |
744 | ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080); | 728 | ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080); |
745 | reg = ac97_read(codec, AC97_EXTENDED_MID); | 729 | reg = ac97_read(codec, AC97_EXTENDED_MID); |
746 | ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200); | 730 | ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200); |
747 | wm9713->pll_out = 0; | 731 | wm9713->pll_in = 0; |
748 | return 0; | 732 | return 0; |
749 | } | 733 | } |
750 | 734 | ||
@@ -788,7 +772,6 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, | |||
788 | ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff); | 772 | ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff); |
789 | reg = ac97_read(codec, AC97_HANDSET_RATE); | 773 | reg = ac97_read(codec, AC97_HANDSET_RATE); |
790 | ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f); | 774 | ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f); |
791 | wm9713->pll_out = freq_out; | ||
792 | wm9713->pll_in = freq_in; | 775 | wm9713->pll_in = freq_in; |
793 | 776 | ||
794 | /* wait 10ms AC97 link frames for the link to stabilise */ | 777 | /* wait 10ms AC97 link frames for the link to stabilise */ |
@@ -1132,7 +1115,7 @@ static int wm9713_soc_suspend(struct platform_device *pdev, | |||
1132 | pm_message_t state) | 1115 | pm_message_t state) |
1133 | { | 1116 | { |
1134 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1117 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1135 | struct snd_soc_codec *codec = socdev->codec; | 1118 | struct snd_soc_codec *codec = socdev->card->codec; |
1136 | u16 reg; | 1119 | u16 reg; |
1137 | 1120 | ||
1138 | /* Disable everything except touchpanel - that will be handled | 1121 | /* Disable everything except touchpanel - that will be handled |
@@ -1150,7 +1133,7 @@ static int wm9713_soc_suspend(struct platform_device *pdev, | |||
1150 | static int wm9713_soc_resume(struct platform_device *pdev) | 1133 | static int wm9713_soc_resume(struct platform_device *pdev) |
1151 | { | 1134 | { |
1152 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1135 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1153 | struct snd_soc_codec *codec = socdev->codec; | 1136 | struct snd_soc_codec *codec = socdev->card->codec; |
1154 | struct wm9713_priv *wm9713 = codec->private_data; | 1137 | struct wm9713_priv *wm9713 = codec->private_data; |
1155 | int i, ret; | 1138 | int i, ret; |
1156 | u16 *cache = codec->reg_cache; | 1139 | u16 *cache = codec->reg_cache; |
@@ -1164,8 +1147,8 @@ static int wm9713_soc_resume(struct platform_device *pdev) | |||
1164 | wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1147 | wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1165 | 1148 | ||
1166 | /* do we need to re-start the PLL ? */ | 1149 | /* do we need to re-start the PLL ? */ |
1167 | if (wm9713->pll_out) | 1150 | if (wm9713->pll_in) |
1168 | wm9713_set_pll(codec, 0, wm9713->pll_in, wm9713->pll_out); | 1151 | wm9713_set_pll(codec, 0, wm9713->pll_in, 0); |
1169 | 1152 | ||
1170 | /* only synchronise the codec if warm reset failed */ | 1153 | /* only synchronise the codec if warm reset failed */ |
1171 | if (ret == 0) { | 1154 | if (ret == 0) { |
@@ -1191,10 +1174,11 @@ static int wm9713_soc_probe(struct platform_device *pdev) | |||
1191 | 1174 | ||
1192 | printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION); | 1175 | printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION); |
1193 | 1176 | ||
1194 | socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 1177 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), |
1195 | if (socdev->codec == NULL) | 1178 | GFP_KERNEL); |
1179 | if (socdev->card->codec == NULL) | ||
1196 | return -ENOMEM; | 1180 | return -ENOMEM; |
1197 | codec = socdev->codec; | 1181 | codec = socdev->card->codec; |
1198 | mutex_init(&codec->mutex); | 1182 | mutex_init(&codec->mutex); |
1199 | 1183 | ||
1200 | codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL); | 1184 | codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL); |
@@ -1245,7 +1229,8 @@ static int wm9713_soc_probe(struct platform_device *pdev) | |||
1245 | reg = ac97_read(codec, AC97_CD) & 0x7fff; | 1229 | reg = ac97_read(codec, AC97_CD) & 0x7fff; |
1246 | ac97_write(codec, AC97_CD, reg); | 1230 | ac97_write(codec, AC97_CD, reg); |
1247 | 1231 | ||
1248 | wm9713_add_controls(codec); | 1232 | snd_soc_add_controls(codec, wm9713_snd_ac97_controls, |
1233 | ARRAY_SIZE(wm9713_snd_ac97_controls)); | ||
1249 | wm9713_add_widgets(codec); | 1234 | wm9713_add_widgets(codec); |
1250 | ret = snd_soc_init_card(socdev); | 1235 | ret = snd_soc_init_card(socdev); |
1251 | if (ret < 0) | 1236 | if (ret < 0) |
@@ -1265,15 +1250,15 @@ priv_err: | |||
1265 | kfree(codec->reg_cache); | 1250 | kfree(codec->reg_cache); |
1266 | 1251 | ||
1267 | cache_err: | 1252 | cache_err: |
1268 | kfree(socdev->codec); | 1253 | kfree(socdev->card->codec); |
1269 | socdev->codec = NULL; | 1254 | socdev->card->codec = NULL; |
1270 | return ret; | 1255 | return ret; |
1271 | } | 1256 | } |
1272 | 1257 | ||
1273 | static int wm9713_soc_remove(struct platform_device *pdev) | 1258 | static int wm9713_soc_remove(struct platform_device *pdev) |
1274 | { | 1259 | { |
1275 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1260 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1276 | struct snd_soc_codec *codec = socdev->codec; | 1261 | struct snd_soc_codec *codec = socdev->card->codec; |
1277 | 1262 | ||
1278 | if (codec == NULL) | 1263 | if (codec == NULL) |
1279 | return 0; | 1264 | return 0; |
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 366049d8578c..7af3b5b3a53d 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -286,7 +286,7 @@ static int davinci_pcm_mmap(struct snd_pcm_substream *substream, | |||
286 | runtime->dma_bytes); | 286 | runtime->dma_bytes); |
287 | } | 287 | } |
288 | 288 | ||
289 | struct snd_pcm_ops davinci_pcm_ops = { | 289 | static struct snd_pcm_ops davinci_pcm_ops = { |
290 | .open = davinci_pcm_open, | 290 | .open = davinci_pcm_open, |
291 | .close = davinci_pcm_close, | 291 | .close = davinci_pcm_close, |
292 | .ioctl = snd_pcm_lib_ioctl, | 292 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c index 4935d1bcbd8d..50baef1fe5b4 100644 --- a/sound/soc/davinci/davinci-sffsdr.c +++ b/sound/soc/davinci/davinci-sffsdr.c | |||
@@ -25,7 +25,9 @@ | |||
25 | 25 | ||
26 | #include <asm/dma.h> | 26 | #include <asm/dma.h> |
27 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
28 | #ifdef CONFIG_SFFSDR_FPGA | ||
28 | #include <asm/plat-sffsdr/sffsdr-fpga.h> | 29 | #include <asm/plat-sffsdr/sffsdr-fpga.h> |
30 | #endif | ||
29 | 31 | ||
30 | #include <mach/mcbsp.h> | 32 | #include <mach/mcbsp.h> |
31 | #include <mach/edma.h> | 33 | #include <mach/edma.h> |
@@ -43,6 +45,17 @@ static int sffsdr_hw_params(struct snd_pcm_substream *substream, | |||
43 | int fs; | 45 | int fs; |
44 | int ret = 0; | 46 | int ret = 0; |
45 | 47 | ||
48 | /* Fsref can be 32000, 44100 or 48000. */ | ||
49 | fs = params_rate(params); | ||
50 | |||
51 | #ifndef CONFIG_SFFSDR_FPGA | ||
52 | /* Without the FPGA module, the Fs is fixed at 44100 Hz */ | ||
53 | if (fs != 44100) { | ||
54 | pr_debug("warning: only 44.1 kHz is supported without SFFSDR FPGA module\n"); | ||
55 | return -EINVAL; | ||
56 | } | ||
57 | #endif | ||
58 | |||
46 | /* Set cpu DAI configuration: | 59 | /* Set cpu DAI configuration: |
47 | * CLKX and CLKR are the inputs for the Sample Rate Generator. | 60 | * CLKX and CLKR are the inputs for the Sample Rate Generator. |
48 | * FSX and FSR are outputs, driven by the sample Rate Generator. */ | 61 | * FSX and FSR are outputs, driven by the sample Rate Generator. */ |
@@ -53,12 +66,13 @@ static int sffsdr_hw_params(struct snd_pcm_substream *substream, | |||
53 | if (ret < 0) | 66 | if (ret < 0) |
54 | return ret; | 67 | return ret; |
55 | 68 | ||
56 | /* Fsref can be 32000, 44100 or 48000. */ | ||
57 | fs = params_rate(params); | ||
58 | |||
59 | pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs); | 69 | pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs); |
60 | 70 | ||
71 | #ifndef CONFIG_SFFSDR_FPGA | ||
72 | return 0; | ||
73 | #else | ||
61 | return sffsdr_fpga_set_codec_fs(fs); | 74 | return sffsdr_fpga_set_codec_fs(fs); |
75 | #endif | ||
62 | } | 76 | } |
63 | 77 | ||
64 | static struct snd_soc_ops sffsdr_ops = { | 78 | static struct snd_soc_ops sffsdr_ops = { |
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 95c12b26fe37..9fc908283371 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -1,17 +1,18 @@ | |||
1 | config SND_SOC_OF_SIMPLE | 1 | config SND_SOC_OF_SIMPLE |
2 | tristate | 2 | tristate |
3 | 3 | ||
4 | # ASoC platform support for the Freescale MPC8610 SOC. This compiles drivers | ||
5 | # for the SSI and the Elo DMA controller. You will still need to select | ||
6 | # a platform driver and a codec driver. | ||
4 | config SND_SOC_MPC8610 | 7 | config SND_SOC_MPC8610 |
5 | bool "ALSA SoC support for the MPC8610 SOC" | 8 | tristate |
6 | depends on MPC8610_HPCD | 9 | depends on MPC8610 |
7 | default y if MPC8610 | ||
8 | help | ||
9 | Say Y if you want to add support for codecs attached to the SSI | ||
10 | device on an MPC8610. | ||
11 | 10 | ||
12 | config SND_SOC_MPC8610_HPCD | 11 | config SND_SOC_MPC8610_HPCD |
13 | bool "ALSA SoC support for the Freescale MPC8610 HPCD board" | 12 | tristate "ALSA SoC support for the Freescale MPC8610 HPCD board" |
14 | depends on SND_SOC_MPC8610 | 13 | # I2C is necessary for the CS4270 driver |
14 | depends on MPC8610_HPCD && I2C | ||
15 | select SND_SOC_MPC8610 | ||
15 | select SND_SOC_CS4270 | 16 | select SND_SOC_CS4270 |
16 | select SND_SOC_CS4270_VD33_ERRATA | 17 | select SND_SOC_CS4270_VD33_ERRATA |
17 | default y if MPC8610_HPCD | 18 | default y if MPC8610_HPCD |
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 035da4afec34..f85134c86387 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile | |||
@@ -2,10 +2,13 @@ | |||
2 | obj-$(CONFIG_SND_SOC_OF_SIMPLE) += soc-of-simple.o | 2 | obj-$(CONFIG_SND_SOC_OF_SIMPLE) += soc-of-simple.o |
3 | 3 | ||
4 | # MPC8610 HPCD Machine Support | 4 | # MPC8610 HPCD Machine Support |
5 | obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += mpc8610_hpcd.o | 5 | snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o |
6 | obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o | ||
6 | 7 | ||
7 | # MPC8610 Platform Support | 8 | # MPC8610 Platform Support |
8 | obj-$(CONFIG_SND_SOC_MPC8610) += fsl_ssi.o fsl_dma.o | 9 | snd-soc-fsl-ssi-objs := fsl_ssi.o |
10 | snd-soc-fsl-dma-objs := fsl_dma.o | ||
11 | obj-$(CONFIG_SND_SOC_MPC8610) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o | ||
9 | 12 | ||
10 | obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o | 13 | obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o |
11 | 14 | ||
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 64993eda5679..58a3fa497503 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
@@ -464,11 +464,7 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) | |||
464 | sizeof(struct fsl_dma_link_descriptor); | 464 | sizeof(struct fsl_dma_link_descriptor); |
465 | 465 | ||
466 | for (i = 0; i < NUM_DMA_LINKS; i++) { | 466 | for (i = 0; i < NUM_DMA_LINKS; i++) { |
467 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | 467 | dma_private->link[i].next = cpu_to_be64(temp_link); |
468 | |||
469 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
470 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
471 | link->next = cpu_to_be64(temp_link); | ||
472 | 468 | ||
473 | temp_link += sizeof(struct fsl_dma_link_descriptor); | 469 | temp_link += sizeof(struct fsl_dma_link_descriptor); |
474 | } | 470 | } |
@@ -525,79 +521,9 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) | |||
525 | * This function obtains hardware parameters about the opened stream and | 521 | * This function obtains hardware parameters about the opened stream and |
526 | * programs the DMA controller accordingly. | 522 | * programs the DMA controller accordingly. |
527 | * | 523 | * |
528 | * Note that due to a quirk of the SSI's STX register, the target address | 524 | * One drawback of big-endian is that when copying integers of different |
529 | * for the DMA operations depends on the sample size. So we don't program | 525 | * sizes to a fixed-sized register, the address to which the integer must be |
530 | * the dest_addr (for playback -- source_addr for capture) fields in the | 526 | * copied is dependent on the size of the integer. |
531 | * link descriptors here. We do that in fsl_dma_prepare() | ||
532 | */ | ||
533 | static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | ||
534 | struct snd_pcm_hw_params *hw_params) | ||
535 | { | ||
536 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
537 | struct fsl_dma_private *dma_private = runtime->private_data; | ||
538 | |||
539 | dma_addr_t temp_addr; /* Pointer to next period */ | ||
540 | |||
541 | unsigned int i; | ||
542 | |||
543 | /* Get all the parameters we need */ | ||
544 | size_t buffer_size = params_buffer_bytes(hw_params); | ||
545 | size_t period_size = params_period_bytes(hw_params); | ||
546 | |||
547 | /* Initialize our DMA tracking variables */ | ||
548 | dma_private->period_size = period_size; | ||
549 | dma_private->num_periods = params_periods(hw_params); | ||
550 | dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size; | ||
551 | dma_private->dma_buf_next = dma_private->dma_buf_phys + | ||
552 | (NUM_DMA_LINKS * period_size); | ||
553 | if (dma_private->dma_buf_next >= dma_private->dma_buf_end) | ||
554 | dma_private->dma_buf_next = dma_private->dma_buf_phys; | ||
555 | |||
556 | /* | ||
557 | * The actual address in STX0 (destination for playback, source for | ||
558 | * capture) is based on the sample size, but we don't know the sample | ||
559 | * size in this function, so we'll have to adjust that later. See | ||
560 | * comments in fsl_dma_prepare(). | ||
561 | * | ||
562 | * The DMA controller does not have a cache, so the CPU does not | ||
563 | * need to tell it to flush its cache. However, the DMA | ||
564 | * controller does need to tell the CPU to flush its cache. | ||
565 | * That's what the SNOOP bit does. | ||
566 | * | ||
567 | * Also, even though the DMA controller supports 36-bit addressing, for | ||
568 | * simplicity we currently support only 32-bit addresses for the audio | ||
569 | * buffer itself. | ||
570 | */ | ||
571 | temp_addr = substream->dma_buffer.addr; | ||
572 | |||
573 | for (i = 0; i < NUM_DMA_LINKS; i++) { | ||
574 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | ||
575 | |||
576 | link->count = cpu_to_be32(period_size); | ||
577 | |||
578 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
579 | link->source_addr = cpu_to_be32(temp_addr); | ||
580 | else | ||
581 | link->dest_addr = cpu_to_be32(temp_addr); | ||
582 | |||
583 | temp_addr += period_size; | ||
584 | } | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | /** | ||
590 | * fsl_dma_prepare - prepare the DMA registers for playback. | ||
591 | * | ||
592 | * This function is called after the specifics of the audio data are known, | ||
593 | * i.e. snd_pcm_runtime is initialized. | ||
594 | * | ||
595 | * In this function, we finish programming the registers of the DMA | ||
596 | * controller that are dependent on the sample size. | ||
597 | * | ||
598 | * One of the drawbacks with big-endian is that when copying integers of | ||
599 | * different sizes to a fixed-sized register, the address to which the | ||
600 | * integer must be copied is dependent on the size of the integer. | ||
601 | * | 527 | * |
602 | * For example, if P is the address of a 32-bit register, and X is a 32-bit | 528 | * For example, if P is the address of a 32-bit register, and X is a 32-bit |
603 | * integer, then X should be copied to address P. However, if X is a 16-bit | 529 | * integer, then X should be copied to address P. However, if X is a 16-bit |
@@ -613,22 +539,58 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
613 | * and 8 bytes at a time). So we do not support packed 24-bit samples. | 539 | * and 8 bytes at a time). So we do not support packed 24-bit samples. |
614 | * 24-bit data must be padded to 32 bits. | 540 | * 24-bit data must be padded to 32 bits. |
615 | */ | 541 | */ |
616 | static int fsl_dma_prepare(struct snd_pcm_substream *substream) | 542 | static int fsl_dma_hw_params(struct snd_pcm_substream *substream, |
543 | struct snd_pcm_hw_params *hw_params) | ||
617 | { | 544 | { |
618 | struct snd_pcm_runtime *runtime = substream->runtime; | 545 | struct snd_pcm_runtime *runtime = substream->runtime; |
619 | struct fsl_dma_private *dma_private = runtime->private_data; | 546 | struct fsl_dma_private *dma_private = runtime->private_data; |
547 | |||
548 | /* Number of bits per sample */ | ||
549 | unsigned int sample_size = | ||
550 | snd_pcm_format_physical_width(params_format(hw_params)); | ||
551 | |||
552 | /* Number of bytes per frame */ | ||
553 | unsigned int frame_size = 2 * (sample_size / 8); | ||
554 | |||
555 | /* Bus address of SSI STX register */ | ||
556 | dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys; | ||
557 | |||
558 | /* Size of the DMA buffer, in bytes */ | ||
559 | size_t buffer_size = params_buffer_bytes(hw_params); | ||
560 | |||
561 | /* Number of bytes per period */ | ||
562 | size_t period_size = params_period_bytes(hw_params); | ||
563 | |||
564 | /* Pointer to next period */ | ||
565 | dma_addr_t temp_addr = substream->dma_buffer.addr; | ||
566 | |||
567 | /* Pointer to DMA controller */ | ||
620 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; | 568 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; |
621 | u32 mr; | 569 | |
570 | u32 mr; /* DMA Mode Register */ | ||
571 | |||
622 | unsigned int i; | 572 | unsigned int i; |
623 | dma_addr_t ssi_sxx_phys; /* Bus address of SSI STX register */ | ||
624 | unsigned int frame_size; /* Number of bytes per frame */ | ||
625 | 573 | ||
626 | ssi_sxx_phys = dma_private->ssi_sxx_phys; | 574 | /* Initialize our DMA tracking variables */ |
575 | dma_private->period_size = period_size; | ||
576 | dma_private->num_periods = params_periods(hw_params); | ||
577 | dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size; | ||
578 | dma_private->dma_buf_next = dma_private->dma_buf_phys + | ||
579 | (NUM_DMA_LINKS * period_size); | ||
580 | |||
581 | if (dma_private->dma_buf_next >= dma_private->dma_buf_end) | ||
582 | /* This happens if the number of periods == NUM_DMA_LINKS */ | ||
583 | dma_private->dma_buf_next = dma_private->dma_buf_phys; | ||
627 | 584 | ||
628 | mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK | | 585 | mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK | |
629 | CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK); | 586 | CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK); |
630 | 587 | ||
631 | switch (runtime->sample_bits) { | 588 | /* Due to a quirk of the SSI's STX register, the target address |
589 | * for the DMA operations depends on the sample size. So we calculate | ||
590 | * that offset here. While we're at it, also tell the DMA controller | ||
591 | * how much data to transfer per sample. | ||
592 | */ | ||
593 | switch (sample_size) { | ||
632 | case 8: | 594 | case 8: |
633 | mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1; | 595 | mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1; |
634 | ssi_sxx_phys += 3; | 596 | ssi_sxx_phys += 3; |
@@ -641,12 +603,12 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream) | |||
641 | mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4; | 603 | mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4; |
642 | break; | 604 | break; |
643 | default: | 605 | default: |
606 | /* We should never get here */ | ||
644 | dev_err(substream->pcm->card->dev, | 607 | dev_err(substream->pcm->card->dev, |
645 | "unsupported sample size %u\n", runtime->sample_bits); | 608 | "unsupported sample size %u\n", sample_size); |
646 | return -EINVAL; | 609 | return -EINVAL; |
647 | } | 610 | } |
648 | 611 | ||
649 | frame_size = runtime->frame_bits / 8; | ||
650 | /* | 612 | /* |
651 | * BWC should always be a multiple of the frame size. BWC determines | 613 | * BWC should always be a multiple of the frame size. BWC determines |
652 | * how many bytes are sent/received before the DMA controller checks the | 614 | * how many bytes are sent/received before the DMA controller checks the |
@@ -655,7 +617,6 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream) | |||
655 | * capture, the receive FIFO is triggered when it contains one frame, so | 617 | * capture, the receive FIFO is triggered when it contains one frame, so |
656 | * we want to receive one frame at a time. | 618 | * we want to receive one frame at a time. |
657 | */ | 619 | */ |
658 | |||
659 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 620 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
660 | mr |= CCSR_DMA_MR_BWC(2 * frame_size); | 621 | mr |= CCSR_DMA_MR_BWC(2 * frame_size); |
661 | else | 622 | else |
@@ -663,16 +624,48 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream) | |||
663 | 624 | ||
664 | out_be32(&dma_channel->mr, mr); | 625 | out_be32(&dma_channel->mr, mr); |
665 | 626 | ||
666 | /* | ||
667 | * Program the address of the DMA transfer to/from the SSI. | ||
668 | */ | ||
669 | for (i = 0; i < NUM_DMA_LINKS; i++) { | 627 | for (i = 0; i < NUM_DMA_LINKS; i++) { |
670 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | 628 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; |
671 | 629 | ||
672 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 630 | link->count = cpu_to_be32(period_size); |
631 | |||
632 | /* Even though the DMA controller supports 36-bit addressing, | ||
633 | * for simplicity we allow only 32-bit addresses for the audio | ||
634 | * buffer itself. This was enforced in fsl_dma_new() with the | ||
635 | * DMA mask. | ||
636 | * | ||
637 | * The snoop bit tells the DMA controller whether it should tell | ||
638 | * the ECM to snoop during a read or write to an address. For | ||
639 | * audio, we use DMA to transfer data between memory and an I/O | ||
640 | * device (the SSI's STX0 or SRX0 register). Snooping is only | ||
641 | * needed if there is a cache, so we need to snoop memory | ||
642 | * addresses only. For playback, that means we snoop the source | ||
643 | * but not the destination. For capture, we snoop the | ||
644 | * destination but not the source. | ||
645 | * | ||
646 | * Note that failing to snoop properly is unlikely to cause | ||
647 | * cache incoherency if the period size is larger than the | ||
648 | * size of L1 cache. This is because filling in one period will | ||
649 | * flush out the data for the previous period. So if you | ||
650 | * increased period_bytes_min to a large enough size, you might | ||
651 | * get more performance by not snooping, and you'll still be | ||
652 | * okay. | ||
653 | */ | ||
654 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
655 | link->source_addr = cpu_to_be32(temp_addr); | ||
656 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
657 | |||
673 | link->dest_addr = cpu_to_be32(ssi_sxx_phys); | 658 | link->dest_addr = cpu_to_be32(ssi_sxx_phys); |
674 | else | 659 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP); |
660 | } else { | ||
675 | link->source_addr = cpu_to_be32(ssi_sxx_phys); | 661 | link->source_addr = cpu_to_be32(ssi_sxx_phys); |
662 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP); | ||
663 | |||
664 | link->dest_addr = cpu_to_be32(temp_addr); | ||
665 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
666 | } | ||
667 | |||
668 | temp_addr += period_size; | ||
676 | } | 669 | } |
677 | 670 | ||
678 | return 0; | 671 | return 0; |
@@ -808,7 +801,6 @@ static struct snd_pcm_ops fsl_dma_ops = { | |||
808 | .ioctl = snd_pcm_lib_ioctl, | 801 | .ioctl = snd_pcm_lib_ioctl, |
809 | .hw_params = fsl_dma_hw_params, | 802 | .hw_params = fsl_dma_hw_params, |
810 | .hw_free = fsl_dma_hw_free, | 803 | .hw_free = fsl_dma_hw_free, |
811 | .prepare = fsl_dma_prepare, | ||
812 | .pointer = fsl_dma_pointer, | 804 | .pointer = fsl_dma_pointer, |
813 | }; | 805 | }; |
814 | 806 | ||
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index c6d6eb71dc1d..6844009833db 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -400,7 +400,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
400 | } | 400 | } |
401 | 401 | ||
402 | /** | 402 | /** |
403 | * fsl_ssi_prepare: prepare the SSI. | 403 | * fsl_ssi_hw_params - program the sample size |
404 | * | 404 | * |
405 | * Most of the SSI registers have been programmed in the startup function, | 405 | * Most of the SSI registers have been programmed in the startup function, |
406 | * but the word length must be programmed here. Unfortunately, programming | 406 | * but the word length must be programmed here. Unfortunately, programming |
@@ -412,20 +412,19 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
412 | * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the | 412 | * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the |
413 | * clock master. | 413 | * clock master. |
414 | */ | 414 | */ |
415 | static int fsl_ssi_prepare(struct snd_pcm_substream *substream, | 415 | static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, |
416 | struct snd_soc_dai *dai) | 416 | struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) |
417 | { | 417 | { |
418 | struct snd_pcm_runtime *runtime = substream->runtime; | 418 | struct fsl_ssi_private *ssi_private = cpu_dai->private_data; |
419 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
420 | struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; | ||
421 | |||
422 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
423 | 419 | ||
424 | if (substream == ssi_private->first_stream) { | 420 | if (substream == ssi_private->first_stream) { |
421 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
422 | unsigned int sample_size = | ||
423 | snd_pcm_format_width(params_format(hw_params)); | ||
425 | u32 wl; | 424 | u32 wl; |
426 | 425 | ||
427 | /* The SSI should always be disabled at this points (SSIEN=0) */ | 426 | /* The SSI should always be disabled at this points (SSIEN=0) */ |
428 | wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); | 427 | wl = CCSR_SSI_SxCCR_WL(sample_size); |
429 | 428 | ||
430 | /* In synchronous mode, the SSI uses STCCR for capture */ | 429 | /* In synchronous mode, the SSI uses STCCR for capture */ |
431 | clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); | 430 | clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); |
@@ -579,7 +578,7 @@ static struct snd_soc_dai fsl_ssi_dai_template = { | |||
579 | }, | 578 | }, |
580 | .ops = { | 579 | .ops = { |
581 | .startup = fsl_ssi_startup, | 580 | .startup = fsl_ssi_startup, |
582 | .prepare = fsl_ssi_prepare, | 581 | .hw_params = fsl_ssi_hw_params, |
583 | .shutdown = fsl_ssi_shutdown, | 582 | .shutdown = fsl_ssi_shutdown, |
584 | .trigger = fsl_ssi_trigger, | 583 | .trigger = fsl_ssi_trigger, |
585 | .set_sysclk = fsl_ssi_set_sysclk, | 584 | .set_sysclk = fsl_ssi_set_sysclk, |
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 4f7f04014585..675732e724d5 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig | |||
@@ -8,7 +8,7 @@ config SND_OMAP_SOC_MCBSP | |||
8 | 8 | ||
9 | config SND_OMAP_SOC_N810 | 9 | config SND_OMAP_SOC_N810 |
10 | tristate "SoC Audio support for Nokia N810" | 10 | tristate "SoC Audio support for Nokia N810" |
11 | depends on SND_OMAP_SOC && MACH_NOKIA_N810 | 11 | depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C |
12 | select SND_OMAP_SOC_MCBSP | 12 | select SND_OMAP_SOC_MCBSP |
13 | select OMAP_MUX | 13 | select OMAP_MUX |
14 | select SND_SOC_TLV320AIC3X | 14 | select SND_SOC_TLV320AIC3X |
@@ -17,7 +17,7 @@ config SND_OMAP_SOC_N810 | |||
17 | 17 | ||
18 | config SND_OMAP_SOC_OSK5912 | 18 | config SND_OMAP_SOC_OSK5912 |
19 | tristate "SoC Audio support for omap osk5912" | 19 | tristate "SoC Audio support for omap osk5912" |
20 | depends on SND_OMAP_SOC && MACH_OMAP_OSK | 20 | depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C |
21 | select SND_OMAP_SOC_MCBSP | 21 | select SND_OMAP_SOC_MCBSP |
22 | select SND_SOC_TLV320AIC23 | 22 | select SND_SOC_TLV320AIC23 |
23 | help | 23 | help |
@@ -55,3 +55,13 @@ config SND_OMAP_SOC_OMAP3_PANDORA | |||
55 | select SND_SOC_TWL4030 | 55 | select SND_SOC_TWL4030 |
56 | help | 56 | help |
57 | Say Y if you want to add support for SoC audio on the OMAP3 Pandora. | 57 | Say Y if you want to add support for SoC audio on the OMAP3 Pandora. |
58 | |||
59 | config SND_OMAP_SOC_OMAP3_BEAGLE | ||
60 | tristate "SoC Audio support for OMAP3 Beagle" | ||
61 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE | ||
62 | select SND_OMAP_SOC_MCBSP | ||
63 | select SND_SOC_TWL4030 | ||
64 | help | ||
65 | Say Y if you want to add support for SoC audio on the Beagleboard. | ||
66 | |||
67 | |||
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 76fedd96e365..0c9e4ac37660 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile | |||
@@ -12,6 +12,7 @@ snd-soc-overo-objs := overo.o | |||
12 | snd-soc-omap2evm-objs := omap2evm.o | 12 | snd-soc-omap2evm-objs := omap2evm.o |
13 | snd-soc-sdp3430-objs := sdp3430.o | 13 | snd-soc-sdp3430-objs := sdp3430.o |
14 | snd-soc-omap3pandora-objs := omap3pandora.o | 14 | snd-soc-omap3pandora-objs := omap3pandora.o |
15 | snd-soc-omap3beagle-objs := omap3beagle.o | ||
15 | 16 | ||
16 | obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o | 17 | obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o |
17 | obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o | 18 | obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o |
@@ -19,3 +20,4 @@ obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o | |||
19 | obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o | 20 | obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o |
20 | obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o | 21 | obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o |
21 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o | 22 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o |
23 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o | ||
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index dd3bb2933762..8e1431cb46bb 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -265,7 +265,7 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream, | |||
265 | runtime->dma_bytes); | 265 | runtime->dma_bytes); |
266 | } | 266 | } |
267 | 267 | ||
268 | struct snd_pcm_ops omap_pcm_ops = { | 268 | static struct snd_pcm_ops omap_pcm_ops = { |
269 | .open = omap_pcm_open, | 269 | .open = omap_pcm_open, |
270 | .close = omap_pcm_close, | 270 | .close = omap_pcm_close, |
271 | .ioctl = snd_pcm_lib_ioctl, | 271 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index fcc2f5d9a878..fe282d4ef422 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c | |||
@@ -143,7 +143,7 @@ static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { | |||
143 | }; | 143 | }; |
144 | 144 | ||
145 | static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = { | 145 | static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = { |
146 | SND_SOC_DAPM_MIC("Mic (Internal)", NULL), | 146 | SND_SOC_DAPM_MIC("Mic (internal)", NULL), |
147 | SND_SOC_DAPM_MIC("Mic (external)", NULL), | 147 | SND_SOC_DAPM_MIC("Mic (external)", NULL), |
148 | SND_SOC_DAPM_LINE("Line In", NULL), | 148 | SND_SOC_DAPM_LINE("Line In", NULL), |
149 | }; | 149 | }; |
@@ -155,16 +155,33 @@ static const struct snd_soc_dapm_route omap3pandora_out_map[] = { | |||
155 | }; | 155 | }; |
156 | 156 | ||
157 | static const struct snd_soc_dapm_route omap3pandora_in_map[] = { | 157 | static const struct snd_soc_dapm_route omap3pandora_in_map[] = { |
158 | {"INL", NULL, "Line In"}, | 158 | {"AUXL", NULL, "Line In"}, |
159 | {"INR", NULL, "Line In"}, | 159 | {"AUXR", NULL, "Line In"}, |
160 | {"INL", NULL, "Mic (Internal)"}, | 160 | |
161 | {"INR", NULL, "Mic (external)"}, | 161 | {"MAINMIC", NULL, "Mic Bias 1"}, |
162 | {"Mic Bias 1", NULL, "Mic (internal)"}, | ||
163 | |||
164 | {"SUBMIC", NULL, "Mic Bias 2"}, | ||
165 | {"Mic Bias 2", NULL, "Mic (external)"}, | ||
162 | }; | 166 | }; |
163 | 167 | ||
164 | static int omap3pandora_out_init(struct snd_soc_codec *codec) | 168 | static int omap3pandora_out_init(struct snd_soc_codec *codec) |
165 | { | 169 | { |
166 | int ret; | 170 | int ret; |
167 | 171 | ||
172 | /* All TWL4030 output pins are floating */ | ||
173 | snd_soc_dapm_nc_pin(codec, "OUTL"); | ||
174 | snd_soc_dapm_nc_pin(codec, "OUTR"); | ||
175 | snd_soc_dapm_nc_pin(codec, "EARPIECE"); | ||
176 | snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); | ||
177 | snd_soc_dapm_nc_pin(codec, "PREDRIVER"); | ||
178 | snd_soc_dapm_nc_pin(codec, "HSOL"); | ||
179 | snd_soc_dapm_nc_pin(codec, "HSOR"); | ||
180 | snd_soc_dapm_nc_pin(codec, "CARKITL"); | ||
181 | snd_soc_dapm_nc_pin(codec, "CARKITR"); | ||
182 | snd_soc_dapm_nc_pin(codec, "HFL"); | ||
183 | snd_soc_dapm_nc_pin(codec, "HFR"); | ||
184 | |||
168 | ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, | 185 | ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, |
169 | ARRAY_SIZE(omap3pandora_out_dapm_widgets)); | 186 | ARRAY_SIZE(omap3pandora_out_dapm_widgets)); |
170 | if (ret < 0) | 187 | if (ret < 0) |
@@ -180,18 +197,11 @@ static int omap3pandora_in_init(struct snd_soc_codec *codec) | |||
180 | { | 197 | { |
181 | int ret; | 198 | int ret; |
182 | 199 | ||
183 | /* All TWL4030 output pins are floating */ | 200 | /* Not comnnected */ |
184 | snd_soc_dapm_nc_pin(codec, "OUTL"), | 201 | snd_soc_dapm_nc_pin(codec, "HSMIC"); |
185 | snd_soc_dapm_nc_pin(codec, "OUTR"), | 202 | snd_soc_dapm_nc_pin(codec, "CARKITMIC"); |
186 | snd_soc_dapm_nc_pin(codec, "EARPIECE"), | 203 | snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); |
187 | snd_soc_dapm_nc_pin(codec, "PREDRIVEL"), | 204 | snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); |
188 | snd_soc_dapm_nc_pin(codec, "PREDRIVER"), | ||
189 | snd_soc_dapm_nc_pin(codec, "HSOL"), | ||
190 | snd_soc_dapm_nc_pin(codec, "HSOR"), | ||
191 | snd_soc_dapm_nc_pin(codec, "CARKITL"), | ||
192 | snd_soc_dapm_nc_pin(codec, "CARKITR"), | ||
193 | snd_soc_dapm_nc_pin(codec, "HFL"), | ||
194 | snd_soc_dapm_nc_pin(codec, "HFR"), | ||
195 | 205 | ||
196 | ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets, | 206 | ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets, |
197 | ARRAY_SIZE(omap3pandora_in_dapm_widgets)); | 207 | ARRAY_SIZE(omap3pandora_in_dapm_widgets)); |
@@ -251,10 +261,9 @@ static int __init omap3pandora_soc_init(void) | |||
251 | { | 261 | { |
252 | int ret; | 262 | int ret; |
253 | 263 | ||
254 | if (!machine_is_omap3_pandora()) { | 264 | if (!machine_is_omap3_pandora()) |
255 | pr_debug(PREFIX "Not OMAP3 Pandora\n"); | ||
256 | return -ENODEV; | 265 | return -ENODEV; |
257 | } | 266 | |
258 | pr_info("OMAP3 Pandora SoC init\n"); | 267 | pr_info("OMAP3 Pandora SoC init\n"); |
259 | 268 | ||
260 | ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power"); | 269 | ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power"); |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index f82e10699471..958ac3fe15d1 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -61,6 +61,24 @@ config SND_PXA2XX_SOC_TOSA | |||
61 | Say Y if you want to add support for SoC audio on Sharp | 61 | Say Y if you want to add support for SoC audio on Sharp |
62 | Zaurus SL-C6000x models (Tosa). | 62 | Zaurus SL-C6000x models (Tosa). |
63 | 63 | ||
64 | config SND_PXA2XX_SOC_E740 | ||
65 | tristate "SoC AC97 Audio support for e740" | ||
66 | depends on SND_PXA2XX_SOC && MACH_E740 | ||
67 | select SND_SOC_WM9705 | ||
68 | select SND_PXA2XX_SOC_AC97 | ||
69 | help | ||
70 | Say Y if you want to add support for SoC audio on the | ||
71 | toshiba e740 PDA | ||
72 | |||
73 | config SND_PXA2XX_SOC_E750 | ||
74 | tristate "SoC AC97 Audio support for e750" | ||
75 | depends on SND_PXA2XX_SOC && MACH_E750 | ||
76 | select SND_SOC_WM9705 | ||
77 | select SND_PXA2XX_SOC_AC97 | ||
78 | help | ||
79 | Say Y if you want to add support for SoC audio on the | ||
80 | toshiba e750 PDA | ||
81 | |||
64 | config SND_PXA2XX_SOC_E800 | 82 | config SND_PXA2XX_SOC_E800 |
65 | tristate "SoC AC97 Audio support for e800" | 83 | tristate "SoC AC97 Audio support for e800" |
66 | depends on SND_PXA2XX_SOC && MACH_E800 | 84 | depends on SND_PXA2XX_SOC && MACH_E800 |
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index 08a9f2797729..97a51a8c936c 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile | |||
@@ -13,6 +13,8 @@ obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o | |||
13 | snd-soc-corgi-objs := corgi.o | 13 | snd-soc-corgi-objs := corgi.o |
14 | snd-soc-poodle-objs := poodle.o | 14 | snd-soc-poodle-objs := poodle.o |
15 | snd-soc-tosa-objs := tosa.o | 15 | snd-soc-tosa-objs := tosa.o |
16 | snd-soc-e740-objs := e740_wm9705.o | ||
17 | snd-soc-e750-objs := e750_wm9705.o | ||
16 | snd-soc-e800-objs := e800_wm9712.o | 18 | snd-soc-e800-objs := e800_wm9712.o |
17 | snd-soc-spitz-objs := spitz.o | 19 | snd-soc-spitz-objs := spitz.o |
18 | snd-soc-em-x270-objs := em-x270.o | 20 | snd-soc-em-x270-objs := em-x270.o |
@@ -22,6 +24,8 @@ snd-soc-zylonite-objs := zylonite.o | |||
22 | obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o | 24 | obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o |
23 | obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o | 25 | obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o |
24 | obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o | 26 | obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o |
27 | obj-$(CONFIG_SND_PXA2XX_SOC_E740) += snd-soc-e740.o | ||
28 | obj-$(CONFIG_SND_PXA2XX_SOC_E750) += snd-soc-e750.o | ||
25 | obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o | 29 | obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o |
26 | obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o | 30 | obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o |
27 | obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o | 31 | obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o |
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c new file mode 100644 index 000000000000..7cd2f89d7b10 --- /dev/null +++ b/sound/soc/pxa/e740_wm9705.c | |||
@@ -0,0 +1,211 @@ | |||
1 | /* | ||
2 | * e740-wm9705.c -- SoC audio for e740 | ||
3 | * | ||
4 | * Copyright 2007 (c) Ian Molton <spyro@f2s.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; version 2 ONLY. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/gpio.h> | ||
15 | |||
16 | #include <sound/core.h> | ||
17 | #include <sound/pcm.h> | ||
18 | #include <sound/soc.h> | ||
19 | #include <sound/soc-dapm.h> | ||
20 | |||
21 | #include <mach/audio.h> | ||
22 | #include <mach/eseries-gpio.h> | ||
23 | |||
24 | #include <asm/mach-types.h> | ||
25 | |||
26 | #include "../codecs/wm9705.h" | ||
27 | #include "pxa2xx-pcm.h" | ||
28 | #include "pxa2xx-ac97.h" | ||
29 | |||
30 | |||
31 | #define E740_AUDIO_OUT 1 | ||
32 | #define E740_AUDIO_IN 2 | ||
33 | |||
34 | static int e740_audio_power; | ||
35 | |||
36 | static void e740_sync_audio_power(int status) | ||
37 | { | ||
38 | gpio_set_value(GPIO_E740_WM9705_nAVDD2, !status); | ||
39 | gpio_set_value(GPIO_E740_AMP_ON, (status & E740_AUDIO_OUT) ? 1 : 0); | ||
40 | gpio_set_value(GPIO_E740_MIC_ON, (status & E740_AUDIO_IN) ? 1 : 0); | ||
41 | } | ||
42 | |||
43 | static int e740_mic_amp_event(struct snd_soc_dapm_widget *w, | ||
44 | struct snd_kcontrol *kcontrol, int event) | ||
45 | { | ||
46 | if (event & SND_SOC_DAPM_PRE_PMU) | ||
47 | e740_audio_power |= E740_AUDIO_IN; | ||
48 | else if (event & SND_SOC_DAPM_POST_PMD) | ||
49 | e740_audio_power &= ~E740_AUDIO_IN; | ||
50 | |||
51 | e740_sync_audio_power(e740_audio_power); | ||
52 | |||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static int e740_output_amp_event(struct snd_soc_dapm_widget *w, | ||
57 | struct snd_kcontrol *kcontrol, int event) | ||
58 | { | ||
59 | if (event & SND_SOC_DAPM_PRE_PMU) | ||
60 | e740_audio_power |= E740_AUDIO_OUT; | ||
61 | else if (event & SND_SOC_DAPM_POST_PMD) | ||
62 | e740_audio_power &= ~E740_AUDIO_OUT; | ||
63 | |||
64 | e740_sync_audio_power(e740_audio_power); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static const struct snd_soc_dapm_widget e740_dapm_widgets[] = { | ||
70 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | ||
71 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
72 | SND_SOC_DAPM_MIC("Mic (Internal)", NULL), | ||
73 | SND_SOC_DAPM_PGA_E("Output Amp", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
74 | e740_output_amp_event, SND_SOC_DAPM_PRE_PMU | | ||
75 | SND_SOC_DAPM_POST_PMD), | ||
76 | SND_SOC_DAPM_PGA_E("Mic Amp", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
77 | e740_mic_amp_event, SND_SOC_DAPM_PRE_PMU | | ||
78 | SND_SOC_DAPM_POST_PMD), | ||
79 | }; | ||
80 | |||
81 | static const struct snd_soc_dapm_route audio_map[] = { | ||
82 | {"Output Amp", NULL, "LOUT"}, | ||
83 | {"Output Amp", NULL, "ROUT"}, | ||
84 | {"Output Amp", NULL, "MONOOUT"}, | ||
85 | |||
86 | {"Speaker", NULL, "Output Amp"}, | ||
87 | {"Headphone Jack", NULL, "Output Amp"}, | ||
88 | |||
89 | {"MIC1", NULL, "Mic Amp"}, | ||
90 | {"Mic Amp", NULL, "Mic (Internal)"}, | ||
91 | }; | ||
92 | |||
93 | static int e740_ac97_init(struct snd_soc_codec *codec) | ||
94 | { | ||
95 | snd_soc_dapm_nc_pin(codec, "HPOUTL"); | ||
96 | snd_soc_dapm_nc_pin(codec, "HPOUTR"); | ||
97 | snd_soc_dapm_nc_pin(codec, "PHONE"); | ||
98 | snd_soc_dapm_nc_pin(codec, "LINEINL"); | ||
99 | snd_soc_dapm_nc_pin(codec, "LINEINR"); | ||
100 | snd_soc_dapm_nc_pin(codec, "CDINL"); | ||
101 | snd_soc_dapm_nc_pin(codec, "CDINR"); | ||
102 | snd_soc_dapm_nc_pin(codec, "PCBEEP"); | ||
103 | snd_soc_dapm_nc_pin(codec, "MIC2"); | ||
104 | |||
105 | snd_soc_dapm_new_controls(codec, e740_dapm_widgets, | ||
106 | ARRAY_SIZE(e740_dapm_widgets)); | ||
107 | |||
108 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | ||
109 | |||
110 | snd_soc_dapm_sync(codec); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static struct snd_soc_dai_link e740_dai[] = { | ||
116 | { | ||
117 | .name = "AC97", | ||
118 | .stream_name = "AC97 HiFi", | ||
119 | .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], | ||
120 | .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI], | ||
121 | .init = e740_ac97_init, | ||
122 | }, | ||
123 | { | ||
124 | .name = "AC97 Aux", | ||
125 | .stream_name = "AC97 Aux", | ||
126 | .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], | ||
127 | .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX], | ||
128 | }, | ||
129 | }; | ||
130 | |||
131 | static struct snd_soc_card e740 = { | ||
132 | .name = "Toshiba e740", | ||
133 | .platform = &pxa2xx_soc_platform, | ||
134 | .dai_link = e740_dai, | ||
135 | .num_links = ARRAY_SIZE(e740_dai), | ||
136 | }; | ||
137 | |||
138 | static struct snd_soc_device e740_snd_devdata = { | ||
139 | .card = &e740, | ||
140 | .codec_dev = &soc_codec_dev_wm9705, | ||
141 | }; | ||
142 | |||
143 | static struct platform_device *e740_snd_device; | ||
144 | |||
145 | static int __init e740_init(void) | ||
146 | { | ||
147 | int ret; | ||
148 | |||
149 | if (!machine_is_e740()) | ||
150 | return -ENODEV; | ||
151 | |||
152 | ret = gpio_request(GPIO_E740_MIC_ON, "Mic amp"); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | ret = gpio_request(GPIO_E740_AMP_ON, "Output amp"); | ||
157 | if (ret) | ||
158 | goto free_mic_amp_gpio; | ||
159 | |||
160 | ret = gpio_request(GPIO_E740_WM9705_nAVDD2, "Audio power"); | ||
161 | if (ret) | ||
162 | goto free_op_amp_gpio; | ||
163 | |||
164 | /* Disable audio */ | ||
165 | ret = gpio_direction_output(GPIO_E740_MIC_ON, 0); | ||
166 | if (ret) | ||
167 | goto free_apwr_gpio; | ||
168 | ret = gpio_direction_output(GPIO_E740_AMP_ON, 0); | ||
169 | if (ret) | ||
170 | goto free_apwr_gpio; | ||
171 | ret = gpio_direction_output(GPIO_E740_WM9705_nAVDD2, 1); | ||
172 | if (ret) | ||
173 | goto free_apwr_gpio; | ||
174 | |||
175 | e740_snd_device = platform_device_alloc("soc-audio", -1); | ||
176 | if (!e740_snd_device) { | ||
177 | ret = -ENOMEM; | ||
178 | goto free_apwr_gpio; | ||
179 | } | ||
180 | |||
181 | platform_set_drvdata(e740_snd_device, &e740_snd_devdata); | ||
182 | e740_snd_devdata.dev = &e740_snd_device->dev; | ||
183 | ret = platform_device_add(e740_snd_device); | ||
184 | |||
185 | if (!ret) | ||
186 | return 0; | ||
187 | |||
188 | /* Fail gracefully */ | ||
189 | platform_device_put(e740_snd_device); | ||
190 | free_apwr_gpio: | ||
191 | gpio_free(GPIO_E740_WM9705_nAVDD2); | ||
192 | free_op_amp_gpio: | ||
193 | gpio_free(GPIO_E740_AMP_ON); | ||
194 | free_mic_amp_gpio: | ||
195 | gpio_free(GPIO_E740_MIC_ON); | ||
196 | |||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | static void __exit e740_exit(void) | ||
201 | { | ||
202 | platform_device_unregister(e740_snd_device); | ||
203 | } | ||
204 | |||
205 | module_init(e740_init); | ||
206 | module_exit(e740_exit); | ||
207 | |||
208 | /* Module information */ | ||
209 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); | ||
210 | MODULE_DESCRIPTION("ALSA SoC driver for e740"); | ||
211 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c new file mode 100644 index 000000000000..8dceccc5e059 --- /dev/null +++ b/sound/soc/pxa/e750_wm9705.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * e750-wm9705.c -- SoC audio for e750 | ||
3 | * | ||
4 | * Copyright 2007 (c) Ian Molton <spyro@f2s.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; version 2 ONLY. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/gpio.h> | ||
15 | |||
16 | #include <sound/core.h> | ||
17 | #include <sound/pcm.h> | ||
18 | #include <sound/soc.h> | ||
19 | #include <sound/soc-dapm.h> | ||
20 | |||
21 | #include <mach/audio.h> | ||
22 | #include <mach/eseries-gpio.h> | ||
23 | |||
24 | #include <asm/mach-types.h> | ||
25 | |||
26 | #include "../codecs/wm9705.h" | ||
27 | #include "pxa2xx-pcm.h" | ||
28 | #include "pxa2xx-ac97.h" | ||
29 | |||
30 | static int e750_spk_amp_event(struct snd_soc_dapm_widget *w, | ||
31 | struct snd_kcontrol *kcontrol, int event) | ||
32 | { | ||
33 | if (event & SND_SOC_DAPM_PRE_PMU) | ||
34 | gpio_set_value(GPIO_E750_SPK_AMP_OFF, 0); | ||
35 | else if (event & SND_SOC_DAPM_POST_PMD) | ||
36 | gpio_set_value(GPIO_E750_SPK_AMP_OFF, 1); | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static int e750_hp_amp_event(struct snd_soc_dapm_widget *w, | ||
42 | struct snd_kcontrol *kcontrol, int event) | ||
43 | { | ||
44 | if (event & SND_SOC_DAPM_PRE_PMU) | ||
45 | gpio_set_value(GPIO_E750_HP_AMP_OFF, 0); | ||
46 | else if (event & SND_SOC_DAPM_POST_PMD) | ||
47 | gpio_set_value(GPIO_E750_HP_AMP_OFF, 1); | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static const struct snd_soc_dapm_widget e750_dapm_widgets[] = { | ||
53 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | ||
54 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
55 | SND_SOC_DAPM_MIC("Mic (Internal)", NULL), | ||
56 | SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
57 | e750_hp_amp_event, SND_SOC_DAPM_PRE_PMU | | ||
58 | SND_SOC_DAPM_POST_PMD), | ||
59 | SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
60 | e750_spk_amp_event, SND_SOC_DAPM_PRE_PMU | | ||
61 | SND_SOC_DAPM_POST_PMD), | ||
62 | }; | ||
63 | |||
64 | static const struct snd_soc_dapm_route audio_map[] = { | ||
65 | {"Headphone Amp", NULL, "HPOUTL"}, | ||
66 | {"Headphone Amp", NULL, "HPOUTR"}, | ||
67 | {"Headphone Jack", NULL, "Headphone Amp"}, | ||
68 | |||
69 | {"Speaker Amp", NULL, "MONOOUT"}, | ||
70 | {"Speaker", NULL, "Speaker Amp"}, | ||
71 | |||
72 | {"MIC1", NULL, "Mic (Internal)"}, | ||
73 | }; | ||
74 | |||
75 | static int e750_ac97_init(struct snd_soc_codec *codec) | ||
76 | { | ||
77 | snd_soc_dapm_nc_pin(codec, "LOUT"); | ||
78 | snd_soc_dapm_nc_pin(codec, "ROUT"); | ||
79 | snd_soc_dapm_nc_pin(codec, "PHONE"); | ||
80 | snd_soc_dapm_nc_pin(codec, "LINEINL"); | ||
81 | snd_soc_dapm_nc_pin(codec, "LINEINR"); | ||
82 | snd_soc_dapm_nc_pin(codec, "CDINL"); | ||
83 | snd_soc_dapm_nc_pin(codec, "CDINR"); | ||
84 | snd_soc_dapm_nc_pin(codec, "PCBEEP"); | ||
85 | snd_soc_dapm_nc_pin(codec, "MIC2"); | ||
86 | |||
87 | snd_soc_dapm_new_controls(codec, e750_dapm_widgets, | ||
88 | ARRAY_SIZE(e750_dapm_widgets)); | ||
89 | |||
90 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | ||
91 | |||
92 | snd_soc_dapm_sync(codec); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static struct snd_soc_dai_link e750_dai[] = { | ||
98 | { | ||
99 | .name = "AC97", | ||
100 | .stream_name = "AC97 HiFi", | ||
101 | .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], | ||
102 | .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI], | ||
103 | .init = e750_ac97_init, | ||
104 | /* use ops to check startup state */ | ||
105 | }, | ||
106 | { | ||
107 | .name = "AC97 Aux", | ||
108 | .stream_name = "AC97 Aux", | ||
109 | .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], | ||
110 | .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX], | ||
111 | }, | ||
112 | }; | ||
113 | |||
114 | static struct snd_soc_card e750 = { | ||
115 | .name = "Toshiba e750", | ||
116 | .platform = &pxa2xx_soc_platform, | ||
117 | .dai_link = e750_dai, | ||
118 | .num_links = ARRAY_SIZE(e750_dai), | ||
119 | }; | ||
120 | |||
121 | static struct snd_soc_device e750_snd_devdata = { | ||
122 | .card = &e750, | ||
123 | .codec_dev = &soc_codec_dev_wm9705, | ||
124 | }; | ||
125 | |||
126 | static struct platform_device *e750_snd_device; | ||
127 | |||
128 | static int __init e750_init(void) | ||
129 | { | ||
130 | int ret; | ||
131 | |||
132 | if (!machine_is_e750()) | ||
133 | return -ENODEV; | ||
134 | |||
135 | ret = gpio_request(GPIO_E750_HP_AMP_OFF, "Headphone amp"); | ||
136 | if (ret) | ||
137 | return ret; | ||
138 | |||
139 | ret = gpio_request(GPIO_E750_SPK_AMP_OFF, "Speaker amp"); | ||
140 | if (ret) | ||
141 | goto free_hp_amp_gpio; | ||
142 | |||
143 | ret = gpio_direction_output(GPIO_E750_HP_AMP_OFF, 1); | ||
144 | if (ret) | ||
145 | goto free_spk_amp_gpio; | ||
146 | |||
147 | ret = gpio_direction_output(GPIO_E750_SPK_AMP_OFF, 1); | ||
148 | if (ret) | ||
149 | goto free_spk_amp_gpio; | ||
150 | |||
151 | e750_snd_device = platform_device_alloc("soc-audio", -1); | ||
152 | if (!e750_snd_device) { | ||
153 | ret = -ENOMEM; | ||
154 | goto free_spk_amp_gpio; | ||
155 | } | ||
156 | |||
157 | platform_set_drvdata(e750_snd_device, &e750_snd_devdata); | ||
158 | e750_snd_devdata.dev = &e750_snd_device->dev; | ||
159 | ret = platform_device_add(e750_snd_device); | ||
160 | |||
161 | if (!ret) | ||
162 | return 0; | ||
163 | |||
164 | /* Fail gracefully */ | ||
165 | platform_device_put(e750_snd_device); | ||
166 | free_spk_amp_gpio: | ||
167 | gpio_free(GPIO_E750_SPK_AMP_OFF); | ||
168 | free_hp_amp_gpio: | ||
169 | gpio_free(GPIO_E750_HP_AMP_OFF); | ||
170 | |||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | static void __exit e750_exit(void) | ||
175 | { | ||
176 | platform_device_unregister(e750_snd_device); | ||
177 | gpio_free(GPIO_E750_SPK_AMP_OFF); | ||
178 | gpio_free(GPIO_E750_HP_AMP_OFF); | ||
179 | } | ||
180 | |||
181 | module_init(e750_init); | ||
182 | module_exit(e750_exit); | ||
183 | |||
184 | /* Module information */ | ||
185 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); | ||
186 | MODULE_DESCRIPTION("ALSA SoC driver for e750"); | ||
187 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index 2e3386dfa0f0..bc019cdce429 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * e800-wm9712.c -- SoC audio for e800 | 2 | * e800-wm9712.c -- SoC audio for e800 |
3 | * | 3 | * |
4 | * Based on tosa.c | ||
5 | * | ||
6 | * Copyright 2007 (c) Ian Molton <spyro@f2s.com> | 4 | * Copyright 2007 (c) Ian Molton <spyro@f2s.com> |
7 | * | 5 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
@@ -13,7 +11,7 @@ | |||
13 | 11 | ||
14 | #include <linux/module.h> | 12 | #include <linux/module.h> |
15 | #include <linux/moduleparam.h> | 13 | #include <linux/moduleparam.h> |
16 | #include <linux/device.h> | 14 | #include <linux/gpio.h> |
17 | 15 | ||
18 | #include <sound/core.h> | 16 | #include <sound/core.h> |
19 | #include <sound/pcm.h> | 17 | #include <sound/pcm.h> |
@@ -21,23 +19,85 @@ | |||
21 | #include <sound/soc-dapm.h> | 19 | #include <sound/soc-dapm.h> |
22 | 20 | ||
23 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
24 | #include <mach/pxa-regs.h> | ||
25 | #include <mach/hardware.h> | ||
26 | #include <mach/audio.h> | 22 | #include <mach/audio.h> |
23 | #include <mach/eseries-gpio.h> | ||
27 | 24 | ||
28 | #include "../codecs/wm9712.h" | 25 | #include "../codecs/wm9712.h" |
29 | #include "pxa2xx-pcm.h" | 26 | #include "pxa2xx-pcm.h" |
30 | #include "pxa2xx-ac97.h" | 27 | #include "pxa2xx-ac97.h" |
31 | 28 | ||
32 | static struct snd_soc_card e800; | 29 | static int e800_spk_amp_event(struct snd_soc_dapm_widget *w, |
30 | struct snd_kcontrol *kcontrol, int event) | ||
31 | { | ||
32 | if (event & SND_SOC_DAPM_PRE_PMU) | ||
33 | gpio_set_value(GPIO_E800_SPK_AMP_ON, 1); | ||
34 | else if (event & SND_SOC_DAPM_POST_PMD) | ||
35 | gpio_set_value(GPIO_E800_SPK_AMP_ON, 0); | ||
33 | 36 | ||
34 | static struct snd_soc_dai_link e800_dai[] = { | 37 | return 0; |
38 | } | ||
39 | |||
40 | static int e800_hp_amp_event(struct snd_soc_dapm_widget *w, | ||
41 | struct snd_kcontrol *kcontrol, int event) | ||
42 | { | ||
43 | if (event & SND_SOC_DAPM_PRE_PMU) | ||
44 | gpio_set_value(GPIO_E800_HP_AMP_OFF, 0); | ||
45 | else if (event & SND_SOC_DAPM_POST_PMD) | ||
46 | gpio_set_value(GPIO_E800_HP_AMP_OFF, 1); | ||
47 | |||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static const struct snd_soc_dapm_widget e800_dapm_widgets[] = { | ||
52 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | ||
53 | SND_SOC_DAPM_MIC("Mic (Internal1)", NULL), | ||
54 | SND_SOC_DAPM_MIC("Mic (Internal2)", NULL), | ||
55 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
56 | SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
57 | e800_hp_amp_event, SND_SOC_DAPM_PRE_PMU | | ||
58 | SND_SOC_DAPM_POST_PMD), | ||
59 | SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
60 | e800_spk_amp_event, SND_SOC_DAPM_PRE_PMU | | ||
61 | SND_SOC_DAPM_POST_PMD), | ||
62 | }; | ||
63 | |||
64 | static const struct snd_soc_dapm_route audio_map[] = { | ||
65 | {"Headphone Jack", NULL, "HPOUTL"}, | ||
66 | {"Headphone Jack", NULL, "HPOUTR"}, | ||
67 | {"Headphone Jack", NULL, "Headphone Amp"}, | ||
68 | |||
69 | {"Speaker Amp", NULL, "MONOOUT"}, | ||
70 | {"Speaker", NULL, "Speaker Amp"}, | ||
71 | |||
72 | {"MIC1", NULL, "Mic (Internal1)"}, | ||
73 | {"MIC2", NULL, "Mic (Internal2)"}, | ||
74 | }; | ||
75 | |||
76 | static int e800_ac97_init(struct snd_soc_codec *codec) | ||
35 | { | 77 | { |
36 | .name = "AC97 Aux", | 78 | snd_soc_dapm_new_controls(codec, e800_dapm_widgets, |
37 | .stream_name = "AC97 Aux", | 79 | ARRAY_SIZE(e800_dapm_widgets)); |
38 | .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], | 80 | |
39 | .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], | 81 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); |
40 | }, | 82 | snd_soc_dapm_sync(codec); |
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static struct snd_soc_dai_link e800_dai[] = { | ||
88 | { | ||
89 | .name = "AC97", | ||
90 | .stream_name = "AC97 HiFi", | ||
91 | .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], | ||
92 | .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], | ||
93 | .init = e800_ac97_init, | ||
94 | }, | ||
95 | { | ||
96 | .name = "AC97 Aux", | ||
97 | .stream_name = "AC97 Aux", | ||
98 | .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], | ||
99 | .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], | ||
100 | }, | ||
41 | }; | 101 | }; |
42 | 102 | ||
43 | static struct snd_soc_card e800 = { | 103 | static struct snd_soc_card e800 = { |
@@ -61,6 +121,22 @@ static int __init e800_init(void) | |||
61 | if (!machine_is_e800()) | 121 | if (!machine_is_e800()) |
62 | return -ENODEV; | 122 | return -ENODEV; |
63 | 123 | ||
124 | ret = gpio_request(GPIO_E800_HP_AMP_OFF, "Headphone amp"); | ||
125 | if (ret) | ||
126 | return ret; | ||
127 | |||
128 | ret = gpio_request(GPIO_E800_SPK_AMP_ON, "Speaker amp"); | ||
129 | if (ret) | ||
130 | goto free_hp_amp_gpio; | ||
131 | |||
132 | ret = gpio_direction_output(GPIO_E800_HP_AMP_OFF, 1); | ||
133 | if (ret) | ||
134 | goto free_spk_amp_gpio; | ||
135 | |||
136 | ret = gpio_direction_output(GPIO_E800_SPK_AMP_ON, 1); | ||
137 | if (ret) | ||
138 | goto free_spk_amp_gpio; | ||
139 | |||
64 | e800_snd_device = platform_device_alloc("soc-audio", -1); | 140 | e800_snd_device = platform_device_alloc("soc-audio", -1); |
65 | if (!e800_snd_device) | 141 | if (!e800_snd_device) |
66 | return -ENOMEM; | 142 | return -ENOMEM; |
@@ -69,8 +145,15 @@ static int __init e800_init(void) | |||
69 | e800_snd_devdata.dev = &e800_snd_device->dev; | 145 | e800_snd_devdata.dev = &e800_snd_device->dev; |
70 | ret = platform_device_add(e800_snd_device); | 146 | ret = platform_device_add(e800_snd_device); |
71 | 147 | ||
72 | if (ret) | 148 | if (!ret) |
73 | platform_device_put(e800_snd_device); | 149 | return 0; |
150 | |||
151 | /* Fail gracefully */ | ||
152 | platform_device_put(e800_snd_device); | ||
153 | free_spk_amp_gpio: | ||
154 | gpio_free(GPIO_E800_SPK_AMP_ON); | ||
155 | free_hp_amp_gpio: | ||
156 | gpio_free(GPIO_E800_HP_AMP_OFF); | ||
74 | 157 | ||
75 | return ret; | 158 | return ret; |
76 | } | 159 | } |
@@ -78,6 +161,8 @@ static int __init e800_init(void) | |||
78 | static void __exit e800_exit(void) | 161 | static void __exit e800_exit(void) |
79 | { | 162 | { |
80 | platform_device_unregister(e800_snd_device); | 163 | platform_device_unregister(e800_snd_device); |
164 | gpio_free(GPIO_E800_SPK_AMP_ON); | ||
165 | gpio_free(GPIO_E800_HP_AMP_OFF); | ||
81 | } | 166 | } |
82 | 167 | ||
83 | module_init(e800_init); | 168 | module_init(e800_init); |
@@ -86,4 +171,4 @@ module_exit(e800_exit); | |||
86 | /* Module information */ | 171 | /* Module information */ |
87 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); | 172 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); |
88 | MODULE_DESCRIPTION("ALSA SoC driver for e800"); | 173 | MODULE_DESCRIPTION("ALSA SoC driver for e800"); |
89 | MODULE_LICENSE("GPL"); | 174 | MODULE_LICENSE("GPL v2"); |
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 73cb6b4c2f2d..4a973ab710be 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | 23 | ||
24 | #include <asm/irq.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/initval.h> | 28 | #include <sound/initval.h> |
@@ -221,9 +223,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, | |||
221 | int ret = 0; | 223 | int ret = 0; |
222 | 224 | ||
223 | if (!cpu_dai->active) { | 225 | if (!cpu_dai->active) { |
224 | ret = ssp_init(&priv->dev, cpu_dai->id + 1, SSP_NO_IRQ); | 226 | priv->dev.port = cpu_dai->id + 1; |
225 | if (ret < 0) | 227 | priv->dev.irq = NO_IRQ; |
226 | return ret; | 228 | clk_enable(priv->dev.ssp->clk); |
227 | ssp_disable(&priv->dev); | 229 | ssp_disable(&priv->dev); |
228 | } | 230 | } |
229 | return ret; | 231 | return ret; |
@@ -238,7 +240,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, | |||
238 | 240 | ||
239 | if (!cpu_dai->active) { | 241 | if (!cpu_dai->active) { |
240 | ssp_disable(&priv->dev); | 242 | ssp_disable(&priv->dev); |
241 | ssp_exit(&priv->dev); | 243 | clk_disable(priv->dev.ssp->clk); |
242 | } | 244 | } |
243 | } | 245 | } |
244 | 246 | ||
@@ -751,7 +753,7 @@ static int pxa_ssp_probe(struct platform_device *pdev, | |||
751 | if (!priv) | 753 | if (!priv) |
752 | return -ENOMEM; | 754 | return -ENOMEM; |
753 | 755 | ||
754 | priv->dev.ssp = ssp_request(dai->id, "SoC audio"); | 756 | priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio"); |
755 | if (priv->dev.ssp == NULL) { | 757 | if (priv->dev.ssp == NULL) { |
756 | ret = -ENODEV; | 758 | ret = -ENODEV; |
757 | goto err_priv; | 759 | goto err_priv; |
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c index f8e9ecd589d3..ec2fb764b241 100644 --- a/sound/soc/pxa/zylonite.c +++ b/sound/soc/pxa/zylonite.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/moduleparam.h> | 15 | #include <linux/moduleparam.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/clk.h> | ||
17 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
18 | #include <sound/core.h> | 19 | #include <sound/core.h> |
19 | #include <sound/pcm.h> | 20 | #include <sound/pcm.h> |
@@ -26,6 +27,17 @@ | |||
26 | #include "pxa2xx-ac97.h" | 27 | #include "pxa2xx-ac97.h" |
27 | #include "pxa-ssp.h" | 28 | #include "pxa-ssp.h" |
28 | 29 | ||
30 | /* | ||
31 | * There is a physical switch SW15 on the board which changes the MCLK | ||
32 | * for the WM9713 between the standard AC97 master clock and the | ||
33 | * output of the CLK_POUT signal from the PXA. | ||
34 | */ | ||
35 | static int clk_pout; | ||
36 | module_param(clk_pout, int, 0); | ||
37 | MODULE_PARM_DESC(clk_pout, "Use CLK_POUT as WM9713 MCLK (SW15 on board)."); | ||
38 | |||
39 | static struct clk *pout; | ||
40 | |||
29 | static struct snd_soc_card zylonite; | 41 | static struct snd_soc_card zylonite; |
30 | 42 | ||
31 | static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = { | 43 | static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = { |
@@ -61,10 +73,8 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
61 | 73 | ||
62 | static int zylonite_wm9713_init(struct snd_soc_codec *codec) | 74 | static int zylonite_wm9713_init(struct snd_soc_codec *codec) |
63 | { | 75 | { |
64 | /* Currently we only support use of the AC97 clock here. If | 76 | if (clk_pout) |
65 | * CLK_POUT is selected by SW15 then the clock API will need | 77 | snd_soc_dai_set_pll(&codec->dai[0], 0, clk_get_rate(pout), 0); |
66 | * to be used to request and enable it here. | ||
67 | */ | ||
68 | 78 | ||
69 | snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, | 79 | snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, |
70 | ARRAY_SIZE(zylonite_dapm_widgets)); | 80 | ARRAY_SIZE(zylonite_dapm_widgets)); |
@@ -135,11 +145,12 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream, | |||
135 | if (ret < 0) | 145 | if (ret < 0) |
136 | return ret; | 146 | return ret; |
137 | 147 | ||
138 | /* Note that if the PLL is in use the WM9713_PCMCLK_PLL_DIV needs | 148 | if (clk_pout) |
139 | * to be set instead. | 149 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV, |
140 | */ | 150 | WM9713_PCMDIV(wm9713_div)); |
141 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV, | 151 | else |
142 | WM9713_PCMDIV(wm9713_div)); | 152 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV, |
153 | WM9713_PCMDIV(wm9713_div)); | ||
143 | if (ret < 0) | 154 | if (ret < 0) |
144 | return ret; | 155 | return ret; |
145 | 156 | ||
@@ -173,8 +184,72 @@ static struct snd_soc_dai_link zylonite_dai[] = { | |||
173 | }, | 184 | }, |
174 | }; | 185 | }; |
175 | 186 | ||
187 | static int zylonite_probe(struct platform_device *pdev) | ||
188 | { | ||
189 | int ret; | ||
190 | |||
191 | if (clk_pout) { | ||
192 | pout = clk_get(NULL, "CLK_POUT"); | ||
193 | if (IS_ERR(pout)) { | ||
194 | dev_err(&pdev->dev, "Unable to obtain CLK_POUT: %ld\n", | ||
195 | PTR_ERR(pout)); | ||
196 | return PTR_ERR(pout); | ||
197 | } | ||
198 | |||
199 | ret = clk_enable(pout); | ||
200 | if (ret != 0) { | ||
201 | dev_err(&pdev->dev, "Unable to enable CLK_POUT: %d\n", | ||
202 | ret); | ||
203 | clk_put(pout); | ||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | dev_dbg(&pdev->dev, "MCLK enabled at %luHz\n", | ||
208 | clk_get_rate(pout)); | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int zylonite_remove(struct platform_device *pdev) | ||
215 | { | ||
216 | if (clk_pout) { | ||
217 | clk_disable(pout); | ||
218 | clk_put(pout); | ||
219 | } | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int zylonite_suspend_post(struct platform_device *pdev, | ||
225 | pm_message_t state) | ||
226 | { | ||
227 | if (clk_pout) | ||
228 | clk_disable(pout); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int zylonite_resume_pre(struct platform_device *pdev) | ||
234 | { | ||
235 | int ret = 0; | ||
236 | |||
237 | if (clk_pout) { | ||
238 | ret = clk_enable(pout); | ||
239 | if (ret != 0) | ||
240 | dev_err(&pdev->dev, "Unable to enable CLK_POUT: %d\n", | ||
241 | ret); | ||
242 | } | ||
243 | |||
244 | return ret; | ||
245 | } | ||
246 | |||
176 | static struct snd_soc_card zylonite = { | 247 | static struct snd_soc_card zylonite = { |
177 | .name = "Zylonite", | 248 | .name = "Zylonite", |
249 | .probe = &zylonite_probe, | ||
250 | .remove = &zylonite_remove, | ||
251 | .suspend_post = &zylonite_suspend_post, | ||
252 | .resume_pre = &zylonite_resume_pre, | ||
178 | .platform = &pxa2xx_soc_platform, | 253 | .platform = &pxa2xx_soc_platform, |
179 | .dai_link = zylonite_dai, | 254 | .dai_link = zylonite_dai, |
180 | .num_links = ARRAY_SIZE(zylonite_dai), | 255 | .num_links = ARRAY_SIZE(zylonite_dai), |
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index fcd03acf10f6..e05a71084c32 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig | |||
@@ -48,4 +48,5 @@ config SND_S3C24XX_SOC_S3C24XX_UDA134X | |||
48 | tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" | 48 | tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" |
49 | depends on SND_S3C24XX_SOC | 49 | depends on SND_S3C24XX_SOC |
50 | select SND_S3C24XX_SOC_I2S | 50 | select SND_S3C24XX_SOC_I2S |
51 | select SND_SOC_L3 | ||
51 | select SND_SOC_UDA134X | 52 | select SND_SOC_UDA134X |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 55fdb4abb179..580a1a534ad0 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -234,7 +234,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
234 | cpu_dai->capture.active = codec_dai->capture.active = 1; | 234 | cpu_dai->capture.active = codec_dai->capture.active = 1; |
235 | cpu_dai->active = codec_dai->active = 1; | 235 | cpu_dai->active = codec_dai->active = 1; |
236 | cpu_dai->runtime = runtime; | 236 | cpu_dai->runtime = runtime; |
237 | socdev->codec->active++; | 237 | card->codec->active++; |
238 | mutex_unlock(&pcm_mutex); | 238 | mutex_unlock(&pcm_mutex); |
239 | return 0; | 239 | return 0; |
240 | 240 | ||
@@ -264,7 +264,7 @@ static void close_delayed_work(struct work_struct *work) | |||
264 | struct snd_soc_card *card = container_of(work, struct snd_soc_card, | 264 | struct snd_soc_card *card = container_of(work, struct snd_soc_card, |
265 | delayed_work.work); | 265 | delayed_work.work); |
266 | struct snd_soc_device *socdev = card->socdev; | 266 | struct snd_soc_device *socdev = card->socdev; |
267 | struct snd_soc_codec *codec = socdev->codec; | 267 | struct snd_soc_codec *codec = card->codec; |
268 | struct snd_soc_dai *codec_dai; | 268 | struct snd_soc_dai *codec_dai; |
269 | int i; | 269 | int i; |
270 | 270 | ||
@@ -319,7 +319,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream) | |||
319 | struct snd_soc_platform *platform = card->platform; | 319 | struct snd_soc_platform *platform = card->platform; |
320 | struct snd_soc_dai *cpu_dai = machine->cpu_dai; | 320 | struct snd_soc_dai *cpu_dai = machine->cpu_dai; |
321 | struct snd_soc_dai *codec_dai = machine->codec_dai; | 321 | struct snd_soc_dai *codec_dai = machine->codec_dai; |
322 | struct snd_soc_codec *codec = socdev->codec; | 322 | struct snd_soc_codec *codec = card->codec; |
323 | 323 | ||
324 | mutex_lock(&pcm_mutex); | 324 | mutex_lock(&pcm_mutex); |
325 | 325 | ||
@@ -387,7 +387,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
387 | struct snd_soc_platform *platform = card->platform; | 387 | struct snd_soc_platform *platform = card->platform; |
388 | struct snd_soc_dai *cpu_dai = machine->cpu_dai; | 388 | struct snd_soc_dai *cpu_dai = machine->cpu_dai; |
389 | struct snd_soc_dai *codec_dai = machine->codec_dai; | 389 | struct snd_soc_dai *codec_dai = machine->codec_dai; |
390 | struct snd_soc_codec *codec = socdev->codec; | 390 | struct snd_soc_codec *codec = card->codec; |
391 | int ret = 0; | 391 | int ret = 0; |
392 | 392 | ||
393 | mutex_lock(&pcm_mutex); | 393 | mutex_lock(&pcm_mutex); |
@@ -553,7 +553,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) | |||
553 | struct snd_soc_platform *platform = card->platform; | 553 | struct snd_soc_platform *platform = card->platform; |
554 | struct snd_soc_dai *cpu_dai = machine->cpu_dai; | 554 | struct snd_soc_dai *cpu_dai = machine->cpu_dai; |
555 | struct snd_soc_dai *codec_dai = machine->codec_dai; | 555 | struct snd_soc_dai *codec_dai = machine->codec_dai; |
556 | struct snd_soc_codec *codec = socdev->codec; | 556 | struct snd_soc_codec *codec = card->codec; |
557 | 557 | ||
558 | mutex_lock(&pcm_mutex); | 558 | mutex_lock(&pcm_mutex); |
559 | 559 | ||
@@ -629,7 +629,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) | |||
629 | struct snd_soc_card *card = socdev->card; | 629 | struct snd_soc_card *card = socdev->card; |
630 | struct snd_soc_platform *platform = card->platform; | 630 | struct snd_soc_platform *platform = card->platform; |
631 | struct snd_soc_codec_device *codec_dev = socdev->codec_dev; | 631 | struct snd_soc_codec_device *codec_dev = socdev->codec_dev; |
632 | struct snd_soc_codec *codec = socdev->codec; | 632 | struct snd_soc_codec *codec = card->codec; |
633 | int i; | 633 | int i; |
634 | 634 | ||
635 | /* Due to the resume being scheduled into a workqueue we could | 635 | /* Due to the resume being scheduled into a workqueue we could |
@@ -705,7 +705,7 @@ static void soc_resume_deferred(struct work_struct *work) | |||
705 | struct snd_soc_device *socdev = card->socdev; | 705 | struct snd_soc_device *socdev = card->socdev; |
706 | struct snd_soc_platform *platform = card->platform; | 706 | struct snd_soc_platform *platform = card->platform; |
707 | struct snd_soc_codec_device *codec_dev = socdev->codec_dev; | 707 | struct snd_soc_codec_device *codec_dev = socdev->codec_dev; |
708 | struct snd_soc_codec *codec = socdev->codec; | 708 | struct snd_soc_codec *codec = card->codec; |
709 | struct platform_device *pdev = to_platform_device(socdev->dev); | 709 | struct platform_device *pdev = to_platform_device(socdev->dev); |
710 | int i; | 710 | int i; |
711 | 711 | ||
@@ -982,8 +982,8 @@ static struct platform_driver soc_driver = { | |||
982 | static int soc_new_pcm(struct snd_soc_device *socdev, | 982 | static int soc_new_pcm(struct snd_soc_device *socdev, |
983 | struct snd_soc_dai_link *dai_link, int num) | 983 | struct snd_soc_dai_link *dai_link, int num) |
984 | { | 984 | { |
985 | struct snd_soc_codec *codec = socdev->codec; | ||
986 | struct snd_soc_card *card = socdev->card; | 985 | struct snd_soc_card *card = socdev->card; |
986 | struct snd_soc_codec *codec = card->codec; | ||
987 | struct snd_soc_platform *platform = card->platform; | 987 | struct snd_soc_platform *platform = card->platform; |
988 | struct snd_soc_dai *codec_dai = dai_link->codec_dai; | 988 | struct snd_soc_dai *codec_dai = dai_link->codec_dai; |
989 | struct snd_soc_dai *cpu_dai = dai_link->cpu_dai; | 989 | struct snd_soc_dai *cpu_dai = dai_link->cpu_dai; |
@@ -998,7 +998,7 @@ static int soc_new_pcm(struct snd_soc_device *socdev, | |||
998 | 998 | ||
999 | rtd->dai = dai_link; | 999 | rtd->dai = dai_link; |
1000 | rtd->socdev = socdev; | 1000 | rtd->socdev = socdev; |
1001 | codec_dai->codec = socdev->codec; | 1001 | codec_dai->codec = card->codec; |
1002 | 1002 | ||
1003 | /* check client and interface hw capabilities */ | 1003 | /* check client and interface hw capabilities */ |
1004 | sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name, | 1004 | sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name, |
@@ -1048,9 +1048,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev, | |||
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | /* codec register dump */ | 1050 | /* codec register dump */ |
1051 | static ssize_t soc_codec_reg_show(struct snd_soc_device *devdata, char *buf) | 1051 | static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) |
1052 | { | 1052 | { |
1053 | struct snd_soc_codec *codec = devdata->codec; | ||
1054 | int i, step = 1, count = 0; | 1053 | int i, step = 1, count = 0; |
1055 | 1054 | ||
1056 | if (!codec->reg_cache_size) | 1055 | if (!codec->reg_cache_size) |
@@ -1090,7 +1089,7 @@ static ssize_t codec_reg_show(struct device *dev, | |||
1090 | struct device_attribute *attr, char *buf) | 1089 | struct device_attribute *attr, char *buf) |
1091 | { | 1090 | { |
1092 | struct snd_soc_device *devdata = dev_get_drvdata(dev); | 1091 | struct snd_soc_device *devdata = dev_get_drvdata(dev); |
1093 | return soc_codec_reg_show(devdata, buf); | 1092 | return soc_codec_reg_show(devdata->card->codec, buf); |
1094 | } | 1093 | } |
1095 | 1094 | ||
1096 | static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); | 1095 | static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); |
@@ -1107,12 +1106,10 @@ static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, | |||
1107 | { | 1106 | { |
1108 | ssize_t ret; | 1107 | ssize_t ret; |
1109 | struct snd_soc_codec *codec = file->private_data; | 1108 | struct snd_soc_codec *codec = file->private_data; |
1110 | struct device *card_dev = codec->card->dev; | ||
1111 | struct snd_soc_device *devdata = card_dev->driver_data; | ||
1112 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 1109 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
1113 | if (!buf) | 1110 | if (!buf) |
1114 | return -ENOMEM; | 1111 | return -ENOMEM; |
1115 | ret = soc_codec_reg_show(devdata, buf); | 1112 | ret = soc_codec_reg_show(codec, buf); |
1116 | if (ret >= 0) | 1113 | if (ret >= 0) |
1117 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | 1114 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); |
1118 | kfree(buf); | 1115 | kfree(buf); |
@@ -1309,19 +1306,19 @@ EXPORT_SYMBOL_GPL(snd_soc_test_bits); | |||
1309 | */ | 1306 | */ |
1310 | int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) | 1307 | int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) |
1311 | { | 1308 | { |
1312 | struct snd_soc_codec *codec = socdev->codec; | ||
1313 | struct snd_soc_card *card = socdev->card; | 1309 | struct snd_soc_card *card = socdev->card; |
1314 | int ret = 0, i; | 1310 | struct snd_soc_codec *codec = card->codec; |
1311 | int ret, i; | ||
1315 | 1312 | ||
1316 | mutex_lock(&codec->mutex); | 1313 | mutex_lock(&codec->mutex); |
1317 | 1314 | ||
1318 | /* register a sound card */ | 1315 | /* register a sound card */ |
1319 | codec->card = snd_card_new(idx, xid, codec->owner, 0); | 1316 | ret = snd_card_create(idx, xid, codec->owner, 0, &codec->card); |
1320 | if (!codec->card) { | 1317 | if (ret < 0) { |
1321 | printk(KERN_ERR "asoc: can't create sound card for codec %s\n", | 1318 | printk(KERN_ERR "asoc: can't create sound card for codec %s\n", |
1322 | codec->name); | 1319 | codec->name); |
1323 | mutex_unlock(&codec->mutex); | 1320 | mutex_unlock(&codec->mutex); |
1324 | return -ENODEV; | 1321 | return ret; |
1325 | } | 1322 | } |
1326 | 1323 | ||
1327 | codec->card->dev = socdev->dev; | 1324 | codec->card->dev = socdev->dev; |
@@ -1355,8 +1352,8 @@ EXPORT_SYMBOL_GPL(snd_soc_new_pcms); | |||
1355 | */ | 1352 | */ |
1356 | int snd_soc_init_card(struct snd_soc_device *socdev) | 1353 | int snd_soc_init_card(struct snd_soc_device *socdev) |
1357 | { | 1354 | { |
1358 | struct snd_soc_codec *codec = socdev->codec; | ||
1359 | struct snd_soc_card *card = socdev->card; | 1355 | struct snd_soc_card *card = socdev->card; |
1356 | struct snd_soc_codec *codec = card->codec; | ||
1360 | int ret = 0, i, ac97 = 0, err = 0; | 1357 | int ret = 0, i, ac97 = 0, err = 0; |
1361 | 1358 | ||
1362 | for (i = 0; i < card->num_links; i++) { | 1359 | for (i = 0; i < card->num_links; i++) { |
@@ -1404,7 +1401,7 @@ int snd_soc_init_card(struct snd_soc_device *socdev) | |||
1404 | if (err < 0) | 1401 | if (err < 0) |
1405 | printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); | 1402 | printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); |
1406 | 1403 | ||
1407 | soc_init_codec_debugfs(socdev->codec); | 1404 | soc_init_codec_debugfs(codec); |
1408 | mutex_unlock(&codec->mutex); | 1405 | mutex_unlock(&codec->mutex); |
1409 | 1406 | ||
1410 | out: | 1407 | out: |
@@ -1421,14 +1418,14 @@ EXPORT_SYMBOL_GPL(snd_soc_init_card); | |||
1421 | */ | 1418 | */ |
1422 | void snd_soc_free_pcms(struct snd_soc_device *socdev) | 1419 | void snd_soc_free_pcms(struct snd_soc_device *socdev) |
1423 | { | 1420 | { |
1424 | struct snd_soc_codec *codec = socdev->codec; | 1421 | struct snd_soc_codec *codec = socdev->card->codec; |
1425 | #ifdef CONFIG_SND_SOC_AC97_BUS | 1422 | #ifdef CONFIG_SND_SOC_AC97_BUS |
1426 | struct snd_soc_dai *codec_dai; | 1423 | struct snd_soc_dai *codec_dai; |
1427 | int i; | 1424 | int i; |
1428 | #endif | 1425 | #endif |
1429 | 1426 | ||
1430 | mutex_lock(&codec->mutex); | 1427 | mutex_lock(&codec->mutex); |
1431 | soc_cleanup_codec_debugfs(socdev->codec); | 1428 | soc_cleanup_codec_debugfs(codec); |
1432 | #ifdef CONFIG_SND_SOC_AC97_BUS | 1429 | #ifdef CONFIG_SND_SOC_AC97_BUS |
1433 | for (i = 0; i < codec->num_dai; i++) { | 1430 | for (i = 0; i < codec->num_dai; i++) { |
1434 | codec_dai = &codec->dai[i]; | 1431 | codec_dai = &codec->dai[i]; |
@@ -1495,6 +1492,37 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, | |||
1495 | EXPORT_SYMBOL_GPL(snd_soc_cnew); | 1492 | EXPORT_SYMBOL_GPL(snd_soc_cnew); |
1496 | 1493 | ||
1497 | /** | 1494 | /** |
1495 | * snd_soc_add_controls - add an array of controls to a codec. | ||
1496 | * Convienience function to add a list of controls. Many codecs were | ||
1497 | * duplicating this code. | ||
1498 | * | ||
1499 | * @codec: codec to add controls to | ||
1500 | * @controls: array of controls to add | ||
1501 | * @num_controls: number of elements in the array | ||
1502 | * | ||
1503 | * Return 0 for success, else error. | ||
1504 | */ | ||
1505 | int snd_soc_add_controls(struct snd_soc_codec *codec, | ||
1506 | const struct snd_kcontrol_new *controls, int num_controls) | ||
1507 | { | ||
1508 | struct snd_card *card = codec->card; | ||
1509 | int err, i; | ||
1510 | |||
1511 | for (i = 0; i < num_controls; i++) { | ||
1512 | const struct snd_kcontrol_new *control = &controls[i]; | ||
1513 | err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); | ||
1514 | if (err < 0) { | ||
1515 | dev_err(codec->dev, "%s: Failed to add %s\n", | ||
1516 | codec->name, control->name); | ||
1517 | return err; | ||
1518 | } | ||
1519 | } | ||
1520 | |||
1521 | return 0; | ||
1522 | } | ||
1523 | EXPORT_SYMBOL_GPL(snd_soc_add_controls); | ||
1524 | |||
1525 | /** | ||
1498 | * snd_soc_info_enum_double - enumerated double mixer info callback | 1526 | * snd_soc_info_enum_double - enumerated double mixer info callback |
1499 | * @kcontrol: mixer control | 1527 | * @kcontrol: mixer control |
1500 | * @uinfo: control element information | 1528 | * @uinfo: control element information |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index a2f1da8b4646..f4a8753c84c0 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -54,14 +54,15 @@ | |||
54 | static int dapm_up_seq[] = { | 54 | static int dapm_up_seq[] = { |
55 | snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, | 55 | snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, |
56 | snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac, | 56 | snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac, |
57 | snd_soc_dapm_mixer, snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, | 57 | snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga, |
58 | snd_soc_dapm_spk, snd_soc_dapm_post | 58 | snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post |
59 | }; | 59 | }; |
60 | |||
60 | static int dapm_down_seq[] = { | 61 | static int dapm_down_seq[] = { |
61 | snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, | 62 | snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, |
62 | snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic, | 63 | snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer, |
63 | snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_value_mux, | 64 | snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias, |
64 | snd_soc_dapm_post | 65 | snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post |
65 | }; | 66 | }; |
66 | 67 | ||
67 | static int dapm_status = 1; | 68 | static int dapm_status = 1; |
@@ -101,7 +102,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
101 | { | 102 | { |
102 | switch (w->id) { | 103 | switch (w->id) { |
103 | case snd_soc_dapm_switch: | 104 | case snd_soc_dapm_switch: |
104 | case snd_soc_dapm_mixer: { | 105 | case snd_soc_dapm_mixer: |
106 | case snd_soc_dapm_mixer_named_ctl: { | ||
105 | int val; | 107 | int val; |
106 | struct soc_mixer_control *mc = (struct soc_mixer_control *) | 108 | struct soc_mixer_control *mc = (struct soc_mixer_control *) |
107 | w->kcontrols[i].private_value; | 109 | w->kcontrols[i].private_value; |
@@ -323,15 +325,33 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, | |||
323 | if (path->name != (char*)w->kcontrols[i].name) | 325 | if (path->name != (char*)w->kcontrols[i].name) |
324 | continue; | 326 | continue; |
325 | 327 | ||
326 | /* add dapm control with long name */ | 328 | /* add dapm control with long name. |
327 | name_len = 2 + strlen(w->name) | 329 | * for dapm_mixer this is the concatenation of the |
328 | + strlen(w->kcontrols[i].name); | 330 | * mixer and kcontrol name. |
331 | * for dapm_mixer_named_ctl this is simply the | ||
332 | * kcontrol name. | ||
333 | */ | ||
334 | name_len = strlen(w->kcontrols[i].name) + 1; | ||
335 | if (w->id == snd_soc_dapm_mixer) | ||
336 | name_len += 1 + strlen(w->name); | ||
337 | |||
329 | path->long_name = kmalloc(name_len, GFP_KERNEL); | 338 | path->long_name = kmalloc(name_len, GFP_KERNEL); |
339 | |||
330 | if (path->long_name == NULL) | 340 | if (path->long_name == NULL) |
331 | return -ENOMEM; | 341 | return -ENOMEM; |
332 | 342 | ||
333 | snprintf(path->long_name, name_len, "%s %s", | 343 | switch (w->id) { |
334 | w->name, w->kcontrols[i].name); | 344 | case snd_soc_dapm_mixer: |
345 | default: | ||
346 | snprintf(path->long_name, name_len, "%s %s", | ||
347 | w->name, w->kcontrols[i].name); | ||
348 | break; | ||
349 | case snd_soc_dapm_mixer_named_ctl: | ||
350 | snprintf(path->long_name, name_len, "%s", | ||
351 | w->kcontrols[i].name); | ||
352 | break; | ||
353 | } | ||
354 | |||
335 | path->long_name[name_len - 1] = '\0'; | 355 | path->long_name[name_len - 1] = '\0'; |
336 | 356 | ||
337 | path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, | 357 | path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, |
@@ -687,6 +707,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action) | |||
687 | case snd_soc_dapm_adc: | 707 | case snd_soc_dapm_adc: |
688 | case snd_soc_dapm_pga: | 708 | case snd_soc_dapm_pga: |
689 | case snd_soc_dapm_mixer: | 709 | case snd_soc_dapm_mixer: |
710 | case snd_soc_dapm_mixer_named_ctl: | ||
690 | if (w->name) { | 711 | if (w->name) { |
691 | in = is_connected_input_ep(w); | 712 | in = is_connected_input_ep(w); |
692 | dapm_clear_walk(w->codec); | 713 | dapm_clear_walk(w->codec); |
@@ -760,6 +781,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, | |||
760 | int found = 0; | 781 | int found = 0; |
761 | 782 | ||
762 | if (widget->id != snd_soc_dapm_mixer && | 783 | if (widget->id != snd_soc_dapm_mixer && |
784 | widget->id != snd_soc_dapm_mixer_named_ctl && | ||
763 | widget->id != snd_soc_dapm_switch) | 785 | widget->id != snd_soc_dapm_switch) |
764 | return -ENODEV; | 786 | return -ENODEV; |
765 | 787 | ||
@@ -795,7 +817,7 @@ static ssize_t dapm_widget_show(struct device *dev, | |||
795 | struct device_attribute *attr, char *buf) | 817 | struct device_attribute *attr, char *buf) |
796 | { | 818 | { |
797 | struct snd_soc_device *devdata = dev_get_drvdata(dev); | 819 | struct snd_soc_device *devdata = dev_get_drvdata(dev); |
798 | struct snd_soc_codec *codec = devdata->codec; | 820 | struct snd_soc_codec *codec = devdata->card->codec; |
799 | struct snd_soc_dapm_widget *w; | 821 | struct snd_soc_dapm_widget *w; |
800 | int count = 0; | 822 | int count = 0; |
801 | char *state = "not set"; | 823 | char *state = "not set"; |
@@ -813,6 +835,7 @@ static ssize_t dapm_widget_show(struct device *dev, | |||
813 | case snd_soc_dapm_adc: | 835 | case snd_soc_dapm_adc: |
814 | case snd_soc_dapm_pga: | 836 | case snd_soc_dapm_pga: |
815 | case snd_soc_dapm_mixer: | 837 | case snd_soc_dapm_mixer: |
838 | case snd_soc_dapm_mixer_named_ctl: | ||
816 | if (w->name) | 839 | if (w->name) |
817 | count += sprintf(buf + count, "%s: %s\n", | 840 | count += sprintf(buf + count, "%s: %s\n", |
818 | w->name, w->power ? "On":"Off"); | 841 | w->name, w->power ? "On":"Off"); |
@@ -876,7 +899,7 @@ static void dapm_free_widgets(struct snd_soc_codec *codec) | |||
876 | } | 899 | } |
877 | 900 | ||
878 | static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, | 901 | static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, |
879 | char *pin, int status) | 902 | const char *pin, int status) |
880 | { | 903 | { |
881 | struct snd_soc_dapm_widget *w; | 904 | struct snd_soc_dapm_widget *w; |
882 | 905 | ||
@@ -991,6 +1014,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, | |||
991 | break; | 1014 | break; |
992 | case snd_soc_dapm_switch: | 1015 | case snd_soc_dapm_switch: |
993 | case snd_soc_dapm_mixer: | 1016 | case snd_soc_dapm_mixer: |
1017 | case snd_soc_dapm_mixer_named_ctl: | ||
994 | ret = dapm_connect_mixer(codec, wsource, wsink, path, control); | 1018 | ret = dapm_connect_mixer(codec, wsource, wsink, path, control); |
995 | if (ret != 0) | 1019 | if (ret != 0) |
996 | goto err; | 1020 | goto err; |
@@ -1068,6 +1092,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) | |||
1068 | switch(w->id) { | 1092 | switch(w->id) { |
1069 | case snd_soc_dapm_switch: | 1093 | case snd_soc_dapm_switch: |
1070 | case snd_soc_dapm_mixer: | 1094 | case snd_soc_dapm_mixer: |
1095 | case snd_soc_dapm_mixer_named_ctl: | ||
1071 | dapm_new_mixer(codec, w); | 1096 | dapm_new_mixer(codec, w); |
1072 | break; | 1097 | break; |
1073 | case snd_soc_dapm_mux: | 1098 | case snd_soc_dapm_mux: |
@@ -1527,8 +1552,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); | |||
1527 | int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, | 1552 | int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, |
1528 | enum snd_soc_bias_level level) | 1553 | enum snd_soc_bias_level level) |
1529 | { | 1554 | { |
1530 | struct snd_soc_codec *codec = socdev->codec; | ||
1531 | struct snd_soc_card *card = socdev->card; | 1555 | struct snd_soc_card *card = socdev->card; |
1556 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1532 | int ret = 0; | 1557 | int ret = 0; |
1533 | 1558 | ||
1534 | if (card->set_bias_level) | 1559 | if (card->set_bias_level) |
@@ -1549,7 +1574,7 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, | |||
1549 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 1574 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
1550 | * do any widget power switching. | 1575 | * do any widget power switching. |
1551 | */ | 1576 | */ |
1552 | int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin) | 1577 | int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) |
1553 | { | 1578 | { |
1554 | return snd_soc_dapm_set_pin(codec, pin, 1); | 1579 | return snd_soc_dapm_set_pin(codec, pin, 1); |
1555 | } | 1580 | } |
@@ -1564,7 +1589,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); | |||
1564 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 1589 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
1565 | * do any widget power switching. | 1590 | * do any widget power switching. |
1566 | */ | 1591 | */ |
1567 | int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin) | 1592 | int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) |
1568 | { | 1593 | { |
1569 | return snd_soc_dapm_set_pin(codec, pin, 0); | 1594 | return snd_soc_dapm_set_pin(codec, pin, 0); |
1570 | } | 1595 | } |
@@ -1584,7 +1609,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); | |||
1584 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 1609 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
1585 | * do any widget power switching. | 1610 | * do any widget power switching. |
1586 | */ | 1611 | */ |
1587 | int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin) | 1612 | int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) |
1588 | { | 1613 | { |
1589 | return snd_soc_dapm_set_pin(codec, pin, 0); | 1614 | return snd_soc_dapm_set_pin(codec, pin, 0); |
1590 | } | 1615 | } |
@@ -1599,7 +1624,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); | |||
1599 | * | 1624 | * |
1600 | * Returns 1 for connected otherwise 0. | 1625 | * Returns 1 for connected otherwise 0. |
1601 | */ | 1626 | */ |
1602 | int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin) | 1627 | int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) |
1603 | { | 1628 | { |
1604 | struct snd_soc_dapm_widget *w; | 1629 | struct snd_soc_dapm_widget *w; |
1605 | 1630 | ||
@@ -1620,7 +1645,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); | |||
1620 | */ | 1645 | */ |
1621 | void snd_soc_dapm_free(struct snd_soc_device *socdev) | 1646 | void snd_soc_dapm_free(struct snd_soc_device *socdev) |
1622 | { | 1647 | { |
1623 | struct snd_soc_codec *codec = socdev->codec; | 1648 | struct snd_soc_codec *codec = socdev->card->codec; |
1624 | 1649 | ||
1625 | snd_soc_dapm_sys_remove(socdev->dev); | 1650 | snd_soc_dapm_sys_remove(socdev->dev); |
1626 | dapm_free_widgets(codec); | 1651 | dapm_free_widgets(codec); |
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c new file mode 100644 index 000000000000..ab64a30bedde --- /dev/null +++ b/sound/soc/soc-jack.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * soc-jack.c -- ALSA SoC jack handling | ||
3 | * | ||
4 | * Copyright 2008 Wolfson Microelectronics PLC. | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <sound/jack.h> | ||
15 | #include <sound/soc.h> | ||
16 | #include <sound/soc-dapm.h> | ||
17 | |||
18 | /** | ||
19 | * snd_soc_jack_new - Create a new jack | ||
20 | * @card: ASoC card | ||
21 | * @id: an identifying string for this jack | ||
22 | * @type: a bitmask of enum snd_jack_type values that can be detected by | ||
23 | * this jack | ||
24 | * @jack: structure to use for the jack | ||
25 | * | ||
26 | * Creates a new jack object. | ||
27 | * | ||
28 | * Returns zero if successful, or a negative error code on failure. | ||
29 | * On success jack will be initialised. | ||
30 | */ | ||
31 | int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, | ||
32 | struct snd_soc_jack *jack) | ||
33 | { | ||
34 | jack->card = card; | ||
35 | INIT_LIST_HEAD(&jack->pins); | ||
36 | |||
37 | return snd_jack_new(card->codec->card, id, type, &jack->jack); | ||
38 | } | ||
39 | EXPORT_SYMBOL_GPL(snd_soc_jack_new); | ||
40 | |||
41 | /** | ||
42 | * snd_soc_jack_report - Report the current status for a jack | ||
43 | * | ||
44 | * @jack: the jack | ||
45 | * @status: a bitmask of enum snd_jack_type values that are currently detected. | ||
46 | * @mask: a bitmask of enum snd_jack_type values that being reported. | ||
47 | * | ||
48 | * If configured using snd_soc_jack_add_pins() then the associated | ||
49 | * DAPM pins will be enabled or disabled as appropriate and DAPM | ||
50 | * synchronised. | ||
51 | * | ||
52 | * Note: This function uses mutexes and should be called from a | ||
53 | * context which can sleep (such as a workqueue). | ||
54 | */ | ||
55 | void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | ||
56 | { | ||
57 | struct snd_soc_codec *codec = jack->card->codec; | ||
58 | struct snd_soc_jack_pin *pin; | ||
59 | int enable; | ||
60 | int oldstatus; | ||
61 | |||
62 | if (!jack) { | ||
63 | WARN_ON_ONCE(!jack); | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | mutex_lock(&codec->mutex); | ||
68 | |||
69 | oldstatus = jack->status; | ||
70 | |||
71 | jack->status &= ~mask; | ||
72 | jack->status |= status; | ||
73 | |||
74 | /* The DAPM sync is expensive enough to be worth skipping */ | ||
75 | if (jack->status == oldstatus) | ||
76 | goto out; | ||
77 | |||
78 | list_for_each_entry(pin, &jack->pins, list) { | ||
79 | enable = pin->mask & status; | ||
80 | |||
81 | if (pin->invert) | ||
82 | enable = !enable; | ||
83 | |||
84 | if (enable) | ||
85 | snd_soc_dapm_enable_pin(codec, pin->pin); | ||
86 | else | ||
87 | snd_soc_dapm_disable_pin(codec, pin->pin); | ||
88 | } | ||
89 | |||
90 | snd_soc_dapm_sync(codec); | ||
91 | |||
92 | snd_jack_report(jack->jack, status); | ||
93 | |||
94 | out: | ||
95 | mutex_unlock(&codec->mutex); | ||
96 | } | ||
97 | EXPORT_SYMBOL_GPL(snd_soc_jack_report); | ||
98 | |||
99 | /** | ||
100 | * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack | ||
101 | * | ||
102 | * @jack: ASoC jack | ||
103 | * @count: Number of pins | ||
104 | * @pins: Array of pins | ||
105 | * | ||
106 | * After this function has been called the DAPM pins specified in the | ||
107 | * pins array will have their status updated to reflect the current | ||
108 | * state of the jack whenever the jack status is updated. | ||
109 | */ | ||
110 | int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, | ||
111 | struct snd_soc_jack_pin *pins) | ||
112 | { | ||
113 | int i; | ||
114 | |||
115 | for (i = 0; i < count; i++) { | ||
116 | if (!pins[i].pin) { | ||
117 | printk(KERN_ERR "No name for pin %d\n", i); | ||
118 | return -EINVAL; | ||
119 | } | ||
120 | if (!pins[i].mask) { | ||
121 | printk(KERN_ERR "No mask for pin %d (%s)\n", i, | ||
122 | pins[i].pin); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | |||
126 | INIT_LIST_HEAD(&pins[i].list); | ||
127 | list_add(&(pins[i].list), &jack->pins); | ||
128 | } | ||
129 | |||
130 | /* Update to reflect the last reported status; canned jack | ||
131 | * implementations are likely to set their state before the | ||
132 | * card has an opportunity to associate pins. | ||
133 | */ | ||
134 | snd_soc_jack_report(jack, 0, 0); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins); | ||
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index f87933e48812..ba38912614b4 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c | |||
@@ -1018,9 +1018,10 @@ static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_de | |||
1018 | return -ENOENT; | 1018 | return -ENOENT; |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | card = snd_card_new(index[dev_num], id[dev_num], THIS_MODULE, 0); | 1021 | err = snd_card_create(index[dev_num], id[dev_num], THIS_MODULE, 0, |
1022 | if (card == NULL) | 1022 | &card); |
1023 | return -ENOMEM; | 1023 | if (err < 0) |
1024 | return err; | ||
1024 | 1025 | ||
1025 | strcpy(card->driver, "AMD7930"); | 1026 | strcpy(card->driver, "AMD7930"); |
1026 | strcpy(card->shortname, "Sun AMD7930"); | 1027 | strcpy(card->shortname, "Sun AMD7930"); |
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 41c387587474..7d93fa705ccf 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -1563,6 +1563,7 @@ static int __init cs4231_attach_begin(struct snd_card **rcard) | |||
1563 | { | 1563 | { |
1564 | struct snd_card *card; | 1564 | struct snd_card *card; |
1565 | struct snd_cs4231 *chip; | 1565 | struct snd_cs4231 *chip; |
1566 | int err; | ||
1566 | 1567 | ||
1567 | *rcard = NULL; | 1568 | *rcard = NULL; |
1568 | 1569 | ||
@@ -1574,10 +1575,10 @@ static int __init cs4231_attach_begin(struct snd_card **rcard) | |||
1574 | return -ENOENT; | 1575 | return -ENOENT; |
1575 | } | 1576 | } |
1576 | 1577 | ||
1577 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 1578 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
1578 | sizeof(struct snd_cs4231)); | 1579 | sizeof(struct snd_cs4231), &card); |
1579 | if (card == NULL) | 1580 | if (err < 0) |
1580 | return -ENOMEM; | 1581 | return err; |
1581 | 1582 | ||
1582 | strcpy(card->driver, "CS4231"); | 1583 | strcpy(card->driver, "CS4231"); |
1583 | strcpy(card->shortname, "Sun CS4231"); | 1584 | strcpy(card->shortname, "Sun CS4231"); |
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 23ed6f04a718..af95ff1e126c 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c | |||
@@ -2612,10 +2612,10 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id | |||
2612 | return -ENODEV; | 2612 | return -ENODEV; |
2613 | } | 2613 | } |
2614 | 2614 | ||
2615 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 2615 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
2616 | sizeof(struct snd_dbri)); | 2616 | sizeof(struct snd_dbri), &card); |
2617 | if (card == NULL) | 2617 | if (err < 0) |
2618 | return -ENOMEM; | 2618 | return err; |
2619 | 2619 | ||
2620 | strcpy(card->driver, "DBRI"); | 2620 | strcpy(card->driver, "DBRI"); |
2621 | strcpy(card->shortname, "Sun DBRI"); | 2621 | strcpy(card->shortname, "Sun DBRI"); |
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index 09802e8a6fb8..4c7b051f9d17 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c | |||
@@ -965,12 +965,11 @@ static int __devinit snd_at73c213_probe(struct spi_device *spi) | |||
965 | return PTR_ERR(board->dac_clk); | 965 | return PTR_ERR(board->dac_clk); |
966 | } | 966 | } |
967 | 967 | ||
968 | retval = -ENOMEM; | ||
969 | |||
970 | /* Allocate "card" using some unused identifiers. */ | 968 | /* Allocate "card" using some unused identifiers. */ |
971 | snprintf(id, sizeof id, "at73c213_%d", board->ssc_id); | 969 | snprintf(id, sizeof id, "at73c213_%d", board->ssc_id); |
972 | card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct snd_at73c213)); | 970 | retval = snd_card_create(-1, id, THIS_MODULE, |
973 | if (!card) | 971 | sizeof(struct snd_at73c213), &card); |
972 | if (retval < 0) | ||
974 | goto out; | 973 | goto out; |
975 | 974 | ||
976 | chip = card->private_data; | 975 | chip = card->private_data; |
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c index 41c36b055f6b..09aed2363cc9 100644 --- a/sound/usb/caiaq/caiaq-device.c +++ b/sound/usb/caiaq/caiaq-device.c | |||
@@ -336,9 +336,10 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev) | |||
336 | log("Unable to set up control system (ret=%d)\n", ret); | 336 | log("Unable to set up control system (ret=%d)\n", ret); |
337 | } | 337 | } |
338 | 338 | ||
339 | static struct snd_card* create_card(struct usb_device* usb_dev) | 339 | static int create_card(struct usb_device* usb_dev, struct snd_card **cardp) |
340 | { | 340 | { |
341 | int devnum; | 341 | int devnum; |
342 | int err; | ||
342 | struct snd_card *card; | 343 | struct snd_card *card; |
343 | struct snd_usb_caiaqdev *dev; | 344 | struct snd_usb_caiaqdev *dev; |
344 | 345 | ||
@@ -347,12 +348,12 @@ static struct snd_card* create_card(struct usb_device* usb_dev) | |||
347 | break; | 348 | break; |
348 | 349 | ||
349 | if (devnum >= SNDRV_CARDS) | 350 | if (devnum >= SNDRV_CARDS) |
350 | return NULL; | 351 | return -ENODEV; |
351 | 352 | ||
352 | card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, | 353 | err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, |
353 | sizeof(struct snd_usb_caiaqdev)); | 354 | sizeof(struct snd_usb_caiaqdev), &card); |
354 | if (!card) | 355 | if (err < 0) |
355 | return NULL; | 356 | return err; |
356 | 357 | ||
357 | dev = caiaqdev(card); | 358 | dev = caiaqdev(card); |
358 | dev->chip.dev = usb_dev; | 359 | dev->chip.dev = usb_dev; |
@@ -362,7 +363,8 @@ static struct snd_card* create_card(struct usb_device* usb_dev) | |||
362 | spin_lock_init(&dev->spinlock); | 363 | spin_lock_init(&dev->spinlock); |
363 | snd_card_set_dev(card, &usb_dev->dev); | 364 | snd_card_set_dev(card, &usb_dev->dev); |
364 | 365 | ||
365 | return card; | 366 | *cardp = card; |
367 | return 0; | ||
366 | } | 368 | } |
367 | 369 | ||
368 | static int __devinit init_card(struct snd_usb_caiaqdev *dev) | 370 | static int __devinit init_card(struct snd_usb_caiaqdev *dev) |
@@ -441,10 +443,10 @@ static int __devinit snd_probe(struct usb_interface *intf, | |||
441 | struct snd_card *card; | 443 | struct snd_card *card; |
442 | struct usb_device *device = interface_to_usbdev(intf); | 444 | struct usb_device *device = interface_to_usbdev(intf); |
443 | 445 | ||
444 | card = create_card(device); | 446 | ret = create_card(device, &card); |
445 | 447 | ||
446 | if (!card) | 448 | if (ret < 0) |
447 | return -ENOMEM; | 449 | return ret; |
448 | 450 | ||
449 | usb_set_intfdata(intf, card); | 451 | usb_set_intfdata(intf, card); |
450 | ret = init_card(caiaqdev(card)); | 452 | ret = init_card(caiaqdev(card)); |
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index c709b9563226..eec32e1a3020 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -3463,10 +3463,10 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, | |||
3463 | return -ENXIO; | 3463 | return -ENXIO; |
3464 | } | 3464 | } |
3465 | 3465 | ||
3466 | card = snd_card_new(index[idx], id[idx], THIS_MODULE, 0); | 3466 | err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card); |
3467 | if (card == NULL) { | 3467 | if (err < 0) { |
3468 | snd_printk(KERN_ERR "cannot create card instance %d\n", idx); | 3468 | snd_printk(KERN_ERR "cannot create card instance %d\n", idx); |
3469 | return -ENOMEM; | 3469 | return err; |
3470 | } | 3470 | } |
3471 | 3471 | ||
3472 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 3472 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index 73e59f4403a4..98276aafefe6 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c | |||
@@ -478,19 +478,21 @@ static bool us122l_create_card(struct snd_card *card) | |||
478 | return true; | 478 | return true; |
479 | } | 479 | } |
480 | 480 | ||
481 | static struct snd_card *usx2y_create_card(struct usb_device *device) | 481 | static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) |
482 | { | 482 | { |
483 | int dev; | 483 | int dev; |
484 | struct snd_card *card; | 484 | struct snd_card *card; |
485 | int err; | ||
486 | |||
485 | for (dev = 0; dev < SNDRV_CARDS; ++dev) | 487 | for (dev = 0; dev < SNDRV_CARDS; ++dev) |
486 | if (enable[dev] && !snd_us122l_card_used[dev]) | 488 | if (enable[dev] && !snd_us122l_card_used[dev]) |
487 | break; | 489 | break; |
488 | if (dev >= SNDRV_CARDS) | 490 | if (dev >= SNDRV_CARDS) |
489 | return NULL; | 491 | return -ENODEV; |
490 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 492 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
491 | sizeof(struct us122l)); | 493 | sizeof(struct us122l), &card); |
492 | if (!card) | 494 | if (err < 0) |
493 | return NULL; | 495 | return err; |
494 | snd_us122l_card_used[US122L(card)->chip.index = dev] = 1; | 496 | snd_us122l_card_used[US122L(card)->chip.index = dev] = 1; |
495 | 497 | ||
496 | US122L(card)->chip.dev = device; | 498 | US122L(card)->chip.dev = device; |
@@ -509,46 +511,57 @@ static struct snd_card *usx2y_create_card(struct usb_device *device) | |||
509 | US122L(card)->chip.dev->devnum | 511 | US122L(card)->chip.dev->devnum |
510 | ); | 512 | ); |
511 | snd_card_set_dev(card, &device->dev); | 513 | snd_card_set_dev(card, &device->dev); |
512 | return card; | 514 | *cardp = card; |
515 | return 0; | ||
513 | } | 516 | } |
514 | 517 | ||
515 | static void *us122l_usb_probe(struct usb_interface *intf, | 518 | static int us122l_usb_probe(struct usb_interface *intf, |
516 | const struct usb_device_id *device_id) | 519 | const struct usb_device_id *device_id, |
520 | struct snd_card **cardp) | ||
517 | { | 521 | { |
518 | struct usb_device *device = interface_to_usbdev(intf); | 522 | struct usb_device *device = interface_to_usbdev(intf); |
519 | struct snd_card *card = usx2y_create_card(device); | 523 | struct snd_card *card; |
524 | int err; | ||
520 | 525 | ||
521 | if (!card) | 526 | err = usx2y_create_card(device, &card); |
522 | return NULL; | 527 | if (err < 0) |
528 | return err; | ||
523 | 529 | ||
524 | if (!us122l_create_card(card) || | 530 | if (!us122l_create_card(card)) { |
525 | snd_card_register(card) < 0) { | ||
526 | snd_card_free(card); | 531 | snd_card_free(card); |
527 | return NULL; | 532 | return -EINVAL; |
533 | } | ||
534 | |||
535 | err = snd_card_register(card); | ||
536 | if (err < 0) { | ||
537 | snd_card_free(card); | ||
538 | return err; | ||
528 | } | 539 | } |
529 | 540 | ||
530 | usb_get_dev(device); | 541 | usb_get_dev(device); |
531 | return card; | 542 | *cardp = card; |
543 | return 0; | ||
532 | } | 544 | } |
533 | 545 | ||
534 | static int snd_us122l_probe(struct usb_interface *intf, | 546 | static int snd_us122l_probe(struct usb_interface *intf, |
535 | const struct usb_device_id *id) | 547 | const struct usb_device_id *id) |
536 | { | 548 | { |
537 | struct snd_card *card; | 549 | struct snd_card *card; |
550 | int err; | ||
551 | |||
538 | snd_printdd(KERN_DEBUG"%p:%i\n", | 552 | snd_printdd(KERN_DEBUG"%p:%i\n", |
539 | intf, intf->cur_altsetting->desc.bInterfaceNumber); | 553 | intf, intf->cur_altsetting->desc.bInterfaceNumber); |
540 | if (intf->cur_altsetting->desc.bInterfaceNumber != 1) | 554 | if (intf->cur_altsetting->desc.bInterfaceNumber != 1) |
541 | return 0; | 555 | return 0; |
542 | 556 | ||
543 | card = us122l_usb_probe(usb_get_intf(intf), id); | 557 | err = us122l_usb_probe(usb_get_intf(intf), id, &card); |
544 | 558 | if (err < 0) { | |
545 | if (card) { | 559 | usb_put_intf(intf); |
546 | usb_set_intfdata(intf, card); | 560 | return err; |
547 | return 0; | ||
548 | } | 561 | } |
549 | 562 | ||
550 | usb_put_intf(intf); | 563 | usb_set_intfdata(intf, card); |
551 | return -EIO; | 564 | return 0; |
552 | } | 565 | } |
553 | 566 | ||
554 | static void snd_us122l_disconnect(struct usb_interface *intf) | 567 | static void snd_us122l_disconnect(struct usb_interface *intf) |
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index 11639bd72a51..af8b84954054 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c | |||
@@ -333,18 +333,21 @@ static struct usb_device_id snd_usX2Y_usb_id_table[] = { | |||
333 | { /* terminator */ } | 333 | { /* terminator */ } |
334 | }; | 334 | }; |
335 | 335 | ||
336 | static struct snd_card *usX2Y_create_card(struct usb_device *device) | 336 | static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) |
337 | { | 337 | { |
338 | int dev; | 338 | int dev; |
339 | struct snd_card * card; | 339 | struct snd_card * card; |
340 | int err; | ||
341 | |||
340 | for (dev = 0; dev < SNDRV_CARDS; ++dev) | 342 | for (dev = 0; dev < SNDRV_CARDS; ++dev) |
341 | if (enable[dev] && !snd_usX2Y_card_used[dev]) | 343 | if (enable[dev] && !snd_usX2Y_card_used[dev]) |
342 | break; | 344 | break; |
343 | if (dev >= SNDRV_CARDS) | 345 | if (dev >= SNDRV_CARDS) |
344 | return NULL; | 346 | return -ENODEV; |
345 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct usX2Ydev)); | 347 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
346 | if (!card) | 348 | sizeof(struct usX2Ydev), &card); |
347 | return NULL; | 349 | if (err < 0) |
350 | return err; | ||
348 | snd_usX2Y_card_used[usX2Y(card)->chip.index = dev] = 1; | 351 | snd_usX2Y_card_used[usX2Y(card)->chip.index = dev] = 1; |
349 | card->private_free = snd_usX2Y_card_private_free; | 352 | card->private_free = snd_usX2Y_card_private_free; |
350 | usX2Y(card)->chip.dev = device; | 353 | usX2Y(card)->chip.dev = device; |
@@ -362,26 +365,36 @@ static struct snd_card *usX2Y_create_card(struct usb_device *device) | |||
362 | usX2Y(card)->chip.dev->bus->busnum, usX2Y(card)->chip.dev->devnum | 365 | usX2Y(card)->chip.dev->bus->busnum, usX2Y(card)->chip.dev->devnum |
363 | ); | 366 | ); |
364 | snd_card_set_dev(card, &device->dev); | 367 | snd_card_set_dev(card, &device->dev); |
365 | return card; | 368 | *cardp = card; |
369 | return 0; | ||
366 | } | 370 | } |
367 | 371 | ||
368 | 372 | ||
369 | static void *usX2Y_usb_probe(struct usb_device *device, struct usb_interface *intf, const struct usb_device_id *device_id) | 373 | static int usX2Y_usb_probe(struct usb_device *device, |
374 | struct usb_interface *intf, | ||
375 | const struct usb_device_id *device_id, | ||
376 | struct snd_card **cardp) | ||
370 | { | 377 | { |
371 | int err; | 378 | int err; |
372 | struct snd_card * card; | 379 | struct snd_card * card; |
380 | |||
381 | *cardp = NULL; | ||
373 | if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || | 382 | if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || |
374 | (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && | 383 | (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && |
375 | le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && | 384 | le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && |
376 | le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428) || | 385 | le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) |
377 | !(card = usX2Y_create_card(device))) | 386 | return -EINVAL; |
378 | return NULL; | 387 | |
388 | err = usX2Y_create_card(device, &card); | ||
389 | if (err < 0) | ||
390 | return err; | ||
379 | if ((err = usX2Y_hwdep_new(card, device)) < 0 || | 391 | if ((err = usX2Y_hwdep_new(card, device)) < 0 || |
380 | (err = snd_card_register(card)) < 0) { | 392 | (err = snd_card_register(card)) < 0) { |
381 | snd_card_free(card); | 393 | snd_card_free(card); |
382 | return NULL; | 394 | return err; |
383 | } | 395 | } |
384 | return card; | 396 | *cardp = card; |
397 | return 0; | ||
385 | } | 398 | } |
386 | 399 | ||
387 | /* | 400 | /* |
@@ -389,13 +402,14 @@ static void *usX2Y_usb_probe(struct usb_device *device, struct usb_interface *in | |||
389 | */ | 402 | */ |
390 | static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id) | 403 | static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id) |
391 | { | 404 | { |
392 | void *chip; | 405 | struct snd_card *card; |
393 | chip = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id); | 406 | int err; |
394 | if (chip) { | 407 | |
395 | usb_set_intfdata(intf, chip); | 408 | err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card); |
396 | return 0; | 409 | if (err < 0) |
397 | } else | 410 | return err; |
398 | return -EIO; | 411 | dev_set_drvdata(&intf->dev, card); |
412 | return 0; | ||
399 | } | 413 | } |
400 | 414 | ||
401 | static void snd_usX2Y_disconnect(struct usb_interface *intf) | 415 | static void snd_usX2Y_disconnect(struct usb_interface *intf) |