twl6040.c (7980033bea8a74692fdb987c44ec91b0be8e752b) | twl6040.c (7480389fb0d873ed78619542bf5d2717a7ad7786) |
---|---|
1/* 2 * ALSA SoC TWL6040 codec driver 3 * 4 * Author: Misael Lopez Cruz <x0052729@ti.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * version 2 as published by the Free Software Foundation. --- 62 unchanged lines hidden (view full) --- 71 int hs_power_mode; 72 int hs_power_mode_locked; 73 bool dl1_unmuted; 74 bool dl2_unmuted; 75 u8 dl12_cache[TWL6040_REG_HFRCTL - TWL6040_REG_HSLCTL + 1]; 76 unsigned int clk_in; 77 unsigned int sysclk; 78 struct twl6040_jack_data hs_jack; | 1/* 2 * ALSA SoC TWL6040 codec driver 3 * 4 * Author: Misael Lopez Cruz <x0052729@ti.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * version 2 as published by the Free Software Foundation. --- 62 unchanged lines hidden (view full) --- 71 int hs_power_mode; 72 int hs_power_mode_locked; 73 bool dl1_unmuted; 74 bool dl2_unmuted; 75 u8 dl12_cache[TWL6040_REG_HFRCTL - TWL6040_REG_HSLCTL + 1]; 76 unsigned int clk_in; 77 unsigned int sysclk; 78 struct twl6040_jack_data hs_jack; |
79 struct snd_soc_codec *codec; | 79 struct snd_soc_component *component; |
80 struct mutex mutex; 81}; 82 83/* set of rates for each pll: low-power and high-performance */ 84static const unsigned int lp_rates[] = { 85 8000, 86 11250, 87 16000, --- 13 unchanged lines hidden (view full) --- 101 96000, 102}; 103 104static const struct snd_pcm_hw_constraint_list sysclk_constraints[] = { 105 { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, }, 106 { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, 107}; 108 | 80 struct mutex mutex; 81}; 82 83/* set of rates for each pll: low-power and high-performance */ 84static const unsigned int lp_rates[] = { 85 8000, 86 11250, 87 16000, --- 13 unchanged lines hidden (view full) --- 101 96000, 102}; 103 104static const struct snd_pcm_hw_constraint_list sysclk_constraints[] = { 105 { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, }, 106 { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, 107}; 108 |
109#define to_twl6040(codec) dev_get_drvdata((codec)->dev->parent) | 109#define to_twl6040(component) dev_get_drvdata((component)->dev->parent) |
110 | 110 |
111static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg) | 111static unsigned int twl6040_read(struct snd_soc_component *component, unsigned int reg) |
112{ | 112{ |
113 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 114 struct twl6040 *twl6040 = to_twl6040(codec); | 113 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 114 struct twl6040 *twl6040 = to_twl6040(component); |
115 u8 value; 116 117 if (reg >= TWL6040_CACHEREGNUM) 118 return -EIO; 119 120 switch (reg) { 121 case TWL6040_REG_HSLCTL: 122 case TWL6040_REG_HSRCTL: --- 5 unchanged lines hidden (view full) --- 128 default: 129 value = twl6040_reg_read(twl6040, reg); 130 break; 131 } 132 133 return value; 134} 135 | 115 u8 value; 116 117 if (reg >= TWL6040_CACHEREGNUM) 118 return -EIO; 119 120 switch (reg) { 121 case TWL6040_REG_HSLCTL: 122 case TWL6040_REG_HSRCTL: --- 5 unchanged lines hidden (view full) --- 128 default: 129 value = twl6040_reg_read(twl6040, reg); 130 break; 131 } 132 133 return value; 134} 135 |
136static bool twl6040_can_write_to_chip(struct snd_soc_codec *codec, | 136static bool twl6040_can_write_to_chip(struct snd_soc_component *component, |
137 unsigned int reg) 138{ | 137 unsigned int reg) 138{ |
139 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 139 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
140 141 switch (reg) { 142 case TWL6040_REG_HSLCTL: 143 case TWL6040_REG_HSRCTL: 144 case TWL6040_REG_EARCTL: 145 /* DL1 path */ 146 return priv->dl1_unmuted; 147 case TWL6040_REG_HFLCTL: 148 case TWL6040_REG_HFRCTL: 149 return priv->dl2_unmuted; 150 default: 151 return 1; 152 } 153} 154 | 140 141 switch (reg) { 142 case TWL6040_REG_HSLCTL: 143 case TWL6040_REG_HSRCTL: 144 case TWL6040_REG_EARCTL: 145 /* DL1 path */ 146 return priv->dl1_unmuted; 147 case TWL6040_REG_HFLCTL: 148 case TWL6040_REG_HFRCTL: 149 return priv->dl2_unmuted; 150 default: 151 return 1; 152 } 153} 154 |
155static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec, | 155static inline void twl6040_update_dl12_cache(struct snd_soc_component *component, |
156 u8 reg, u8 value) 157{ | 156 u8 reg, u8 value) 157{ |
158 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 158 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
159 160 switch (reg) { 161 case TWL6040_REG_HSLCTL: 162 case TWL6040_REG_HSRCTL: 163 case TWL6040_REG_EARCTL: 164 case TWL6040_REG_HFLCTL: 165 case TWL6040_REG_HFRCTL: 166 priv->dl12_cache[reg - TWL6040_REG_HSLCTL] = value; 167 break; 168 default: 169 break; 170 } 171} 172 | 159 160 switch (reg) { 161 case TWL6040_REG_HSLCTL: 162 case TWL6040_REG_HSRCTL: 163 case TWL6040_REG_EARCTL: 164 case TWL6040_REG_HFLCTL: 165 case TWL6040_REG_HFRCTL: 166 priv->dl12_cache[reg - TWL6040_REG_HSLCTL] = value; 167 break; 168 default: 169 break; 170 } 171} 172 |
173static int twl6040_write(struct snd_soc_codec *codec, | 173static int twl6040_write(struct snd_soc_component *component, |
174 unsigned int reg, unsigned int value) 175{ | 174 unsigned int reg, unsigned int value) 175{ |
176 struct twl6040 *twl6040 = to_twl6040(codec); | 176 struct twl6040 *twl6040 = to_twl6040(component); |
177 178 if (reg >= TWL6040_CACHEREGNUM) 179 return -EIO; 180 | 177 178 if (reg >= TWL6040_CACHEREGNUM) 179 return -EIO; 180 |
181 twl6040_update_dl12_cache(codec, reg, value); 182 if (twl6040_can_write_to_chip(codec, reg)) | 181 twl6040_update_dl12_cache(component, reg, value); 182 if (twl6040_can_write_to_chip(component, reg)) |
183 return twl6040_reg_write(twl6040, reg, value); 184 else 185 return 0; 186} 187 | 183 return twl6040_reg_write(twl6040, reg, value); 184 else 185 return 0; 186} 187 |
188static void twl6040_init_chip(struct snd_soc_codec *codec) | 188static void twl6040_init_chip(struct snd_soc_component *component) |
189{ | 189{ |
190 twl6040_read(codec, TWL6040_REG_TRIM1); 191 twl6040_read(codec, TWL6040_REG_TRIM2); 192 twl6040_read(codec, TWL6040_REG_TRIM3); 193 twl6040_read(codec, TWL6040_REG_HSOTRIM); 194 twl6040_read(codec, TWL6040_REG_HFOTRIM); | 190 twl6040_read(component, TWL6040_REG_TRIM1); 191 twl6040_read(component, TWL6040_REG_TRIM2); 192 twl6040_read(component, TWL6040_REG_TRIM3); 193 twl6040_read(component, TWL6040_REG_HSOTRIM); 194 twl6040_read(component, TWL6040_REG_HFOTRIM); |
195 196 /* Change chip defaults */ 197 /* No imput selected for microphone amplifiers */ | 195 196 /* Change chip defaults */ 197 /* No imput selected for microphone amplifiers */ |
198 twl6040_write(codec, TWL6040_REG_MICLCTL, 0x18); 199 twl6040_write(codec, TWL6040_REG_MICRCTL, 0x18); | 198 twl6040_write(component, TWL6040_REG_MICLCTL, 0x18); 199 twl6040_write(component, TWL6040_REG_MICRCTL, 0x18); |
200 201 /* 202 * We need to lower the default gain values, so the ramp code 203 * can work correctly for the first playback. 204 * This reduces the pop noise heard at the first playback. 205 */ | 200 201 /* 202 * We need to lower the default gain values, so the ramp code 203 * can work correctly for the first playback. 204 * This reduces the pop noise heard at the first playback. 205 */ |
206 twl6040_write(codec, TWL6040_REG_HSGAIN, 0xff); 207 twl6040_write(codec, TWL6040_REG_EARCTL, 0x1e); 208 twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1d); 209 twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1d); 210 twl6040_write(codec, TWL6040_REG_LINEGAIN, 0); | 206 twl6040_write(component, TWL6040_REG_HSGAIN, 0xff); 207 twl6040_write(component, TWL6040_REG_EARCTL, 0x1e); 208 twl6040_write(component, TWL6040_REG_HFLGAIN, 0x1d); 209 twl6040_write(component, TWL6040_REG_HFRGAIN, 0x1d); 210 twl6040_write(component, TWL6040_REG_LINEGAIN, 0); |
211} 212 213/* set headset dac and driver power mode */ | 211} 212 213/* set headset dac and driver power mode */ |
214static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) | 214static int headset_power_mode(struct snd_soc_component *component, int high_perf) |
215{ 216 int hslctl, hsrctl; 217 int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE; 218 | 215{ 216 int hslctl, hsrctl; 217 int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE; 218 |
219 hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL); 220 hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL); | 219 hslctl = twl6040_read(component, TWL6040_REG_HSLCTL); 220 hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL); |
221 222 if (high_perf) { 223 hslctl &= ~mask; 224 hsrctl &= ~mask; 225 } else { 226 hslctl |= mask; 227 hsrctl |= mask; 228 } 229 | 221 222 if (high_perf) { 223 hslctl &= ~mask; 224 hsrctl &= ~mask; 225 } else { 226 hslctl |= mask; 227 hsrctl |= mask; 228 } 229 |
230 twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl); 231 twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl); | 230 twl6040_write(component, TWL6040_REG_HSLCTL, hslctl); 231 twl6040_write(component, TWL6040_REG_HSRCTL, hsrctl); |
232 233 return 0; 234} 235 236static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, 237 struct snd_kcontrol *kcontrol, int event) 238{ | 232 233 return 0; 234} 235 236static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, 237 struct snd_kcontrol *kcontrol, int event) 238{ |
239 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 239 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
240 u8 hslctl, hsrctl; 241 242 /* 243 * Workaround for Headset DC offset caused pop noise: 244 * Both HS DAC need to be turned on (before the HS driver) and off at 245 * the same time. 246 */ | 240 u8 hslctl, hsrctl; 241 242 /* 243 * Workaround for Headset DC offset caused pop noise: 244 * Both HS DAC need to be turned on (before the HS driver) and off at 245 * the same time. 246 */ |
247 hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL); 248 hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL); | 247 hslctl = twl6040_read(component, TWL6040_REG_HSLCTL); 248 hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL); |
249 if (SND_SOC_DAPM_EVENT_ON(event)) { 250 hslctl |= TWL6040_HSDACENA; 251 hsrctl |= TWL6040_HSDACENA; 252 } else { 253 hslctl &= ~TWL6040_HSDACENA; 254 hsrctl &= ~TWL6040_HSDACENA; 255 } | 249 if (SND_SOC_DAPM_EVENT_ON(event)) { 250 hslctl |= TWL6040_HSDACENA; 251 hsrctl |= TWL6040_HSDACENA; 252 } else { 253 hslctl &= ~TWL6040_HSDACENA; 254 hsrctl &= ~TWL6040_HSDACENA; 255 } |
256 twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl); 257 twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl); | 256 twl6040_write(component, TWL6040_REG_HSLCTL, hslctl); 257 twl6040_write(component, TWL6040_REG_HSRCTL, hsrctl); |
258 259 msleep(1); 260 return 0; 261} 262 263static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w, 264 struct snd_kcontrol *kcontrol, int event) 265{ | 258 259 msleep(1); 260 return 0; 261} 262 263static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w, 264 struct snd_kcontrol *kcontrol, int event) 265{ |
266 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 267 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 266 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 267 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
268 int ret = 0; 269 270 if (SND_SOC_DAPM_EVENT_ON(event)) { 271 /* Earphone doesn't support low power mode */ 272 priv->hs_power_mode_locked = 1; | 268 int ret = 0; 269 270 if (SND_SOC_DAPM_EVENT_ON(event)) { 271 /* Earphone doesn't support low power mode */ 272 priv->hs_power_mode_locked = 1; |
273 ret = headset_power_mode(codec, 1); | 273 ret = headset_power_mode(component, 1); |
274 } else { 275 priv->hs_power_mode_locked = 0; | 274 } else { 275 priv->hs_power_mode_locked = 0; |
276 ret = headset_power_mode(codec, priv->hs_power_mode); | 276 ret = headset_power_mode(component, priv->hs_power_mode); |
277 } 278 279 msleep(1); 280 281 return ret; 282} 283 | 277 } 278 279 msleep(1); 280 281 return ret; 282} 283 |
284static void twl6040_hs_jack_report(struct snd_soc_codec *codec, | 284static void twl6040_hs_jack_report(struct snd_soc_component *component, |
285 struct snd_soc_jack *jack, int report) 286{ | 285 struct snd_soc_jack *jack, int report) 286{ |
287 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 287 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
288 int status; 289 290 mutex_lock(&priv->mutex); 291 292 /* Sync status */ | 288 int status; 289 290 mutex_lock(&priv->mutex); 291 292 /* Sync status */ |
293 status = twl6040_read(codec, TWL6040_REG_STATUS); | 293 status = twl6040_read(component, TWL6040_REG_STATUS); |
294 if (status & TWL6040_PLUGCOMP) 295 snd_soc_jack_report(jack, report, report); 296 else 297 snd_soc_jack_report(jack, 0, report); 298 299 mutex_unlock(&priv->mutex); 300} 301 | 294 if (status & TWL6040_PLUGCOMP) 295 snd_soc_jack_report(jack, report, report); 296 else 297 snd_soc_jack_report(jack, 0, report); 298 299 mutex_unlock(&priv->mutex); 300} 301 |
302void twl6040_hs_jack_detect(struct snd_soc_codec *codec, | 302void twl6040_hs_jack_detect(struct snd_soc_component *component, |
303 struct snd_soc_jack *jack, int report) 304{ | 303 struct snd_soc_jack *jack, int report) 304{ |
305 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 305 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
306 struct twl6040_jack_data *hs_jack = &priv->hs_jack; 307 308 hs_jack->jack = jack; 309 hs_jack->report = report; 310 | 306 struct twl6040_jack_data *hs_jack = &priv->hs_jack; 307 308 hs_jack->jack = jack; 309 hs_jack->report = report; 310 |
311 twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report); | 311 twl6040_hs_jack_report(component, hs_jack->jack, hs_jack->report); |
312} 313EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect); 314 315static void twl6040_accessory_work(struct work_struct *work) 316{ 317 struct twl6040_data *priv = container_of(work, 318 struct twl6040_data, hs_jack.work.work); | 312} 313EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect); 314 315static void twl6040_accessory_work(struct work_struct *work) 316{ 317 struct twl6040_data *priv = container_of(work, 318 struct twl6040_data, hs_jack.work.work); |
319 struct snd_soc_codec *codec = priv->codec; | 319 struct snd_soc_component *component = priv->component; |
320 struct twl6040_jack_data *hs_jack = &priv->hs_jack; 321 | 320 struct twl6040_jack_data *hs_jack = &priv->hs_jack; 321 |
322 twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report); | 322 twl6040_hs_jack_report(component, hs_jack->jack, hs_jack->report); |
323} 324 325/* audio interrupt handler */ 326static irqreturn_t twl6040_audio_handler(int irq, void *data) 327{ | 323} 324 325/* audio interrupt handler */ 326static irqreturn_t twl6040_audio_handler(int irq, void *data) 327{ |
328 struct snd_soc_codec *codec = data; 329 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 328 struct snd_soc_component *component = data; 329 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
330 331 queue_delayed_work(system_power_efficient_wq, 332 &priv->hs_jack.work, msecs_to_jiffies(200)); 333 334 return IRQ_HANDLED; 335} 336 337static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol, 338 struct snd_ctl_elem_value *ucontrol) 339{ | 330 331 queue_delayed_work(system_power_efficient_wq, 332 &priv->hs_jack.work, msecs_to_jiffies(200)); 333 334 return IRQ_HANDLED; 335} 336 337static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol, 338 struct snd_ctl_elem_value *ucontrol) 339{ |
340 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); | 340 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); |
341 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 342 unsigned int val; 343 344 /* Do not allow changes while Input/FF efect is running */ | 341 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 342 unsigned int val; 343 344 /* Do not allow changes while Input/FF efect is running */ |
345 val = twl6040_read(codec, e->reg); | 345 val = twl6040_read(component, e->reg); |
346 if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL)) 347 return -EBUSY; 348 349 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 350} 351 352/* 353 * MICATT volume control: --- 127 unchanged lines hidden (view full) --- 481}; 482 483static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum, 484 twl6040_power_mode_texts); 485 486static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, 487 struct snd_ctl_elem_value *ucontrol) 488{ | 346 if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL)) 347 return -EBUSY; 348 349 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 350} 351 352/* 353 * MICATT volume control: --- 127 unchanged lines hidden (view full) --- 481}; 482 483static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum, 484 twl6040_power_mode_texts); 485 486static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, 487 struct snd_ctl_elem_value *ucontrol) 488{ |
489 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 490 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 489 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 490 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
491 492 ucontrol->value.enumerated.item[0] = priv->hs_power_mode; 493 494 return 0; 495} 496 497static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, 498 struct snd_ctl_elem_value *ucontrol) 499{ | 491 492 ucontrol->value.enumerated.item[0] = priv->hs_power_mode; 493 494 return 0; 495} 496 497static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, 498 struct snd_ctl_elem_value *ucontrol) 499{ |
500 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 501 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 500 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 501 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
502 int high_perf = ucontrol->value.enumerated.item[0]; 503 int ret = 0; 504 505 if (!priv->hs_power_mode_locked) | 502 int high_perf = ucontrol->value.enumerated.item[0]; 503 int ret = 0; 504 505 if (!priv->hs_power_mode_locked) |
506 ret = headset_power_mode(codec, high_perf); | 506 ret = headset_power_mode(component, high_perf); |
507 508 if (!ret) 509 priv->hs_power_mode = high_perf; 510 511 return ret; 512} 513 514static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, 515 struct snd_ctl_elem_value *ucontrol) 516{ | 507 508 if (!ret) 509 priv->hs_power_mode = high_perf; 510 511 return ret; 512} 513 514static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, 515 struct snd_ctl_elem_value *ucontrol) 516{ |
517 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 518 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 517 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 518 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
519 520 ucontrol->value.enumerated.item[0] = priv->pll_power_mode; 521 522 return 0; 523} 524 525static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, 526 struct snd_ctl_elem_value *ucontrol) 527{ | 519 520 ucontrol->value.enumerated.item[0] = priv->pll_power_mode; 521 522 return 0; 523} 524 525static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, 526 struct snd_ctl_elem_value *ucontrol) 527{ |
528 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 529 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 528 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 529 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
530 531 priv->pll_power_mode = ucontrol->value.enumerated.item[0]; 532 533 return 0; 534} 535 | 530 531 priv->pll_power_mode = ucontrol->value.enumerated.item[0]; 532 533 return 0; 534} 535 |
536int twl6040_get_dl1_gain(struct snd_soc_codec *codec) | 536int twl6040_get_dl1_gain(struct snd_soc_component *component) |
537{ | 537{ |
538 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | 538 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); |
539 540 if (snd_soc_dapm_get_pin_status(dapm, "EP")) 541 return -1; /* -1dB */ 542 543 if (snd_soc_dapm_get_pin_status(dapm, "HSOR") || 544 snd_soc_dapm_get_pin_status(dapm, "HSOL")) { 545 | 539 540 if (snd_soc_dapm_get_pin_status(dapm, "EP")) 541 return -1; /* -1dB */ 542 543 if (snd_soc_dapm_get_pin_status(dapm, "HSOR") || 544 snd_soc_dapm_get_pin_status(dapm, "HSOL")) { 545 |
546 u8 val = twl6040_read(codec, TWL6040_REG_HSLCTL); | 546 u8 val = twl6040_read(component, TWL6040_REG_HSLCTL); |
547 if (val & TWL6040_HSDACMODE) 548 /* HSDACL in LP mode */ 549 return -8; /* -8dB */ 550 else 551 /* HSDACL in HP mode */ 552 return -1; /* -1dB */ 553 } 554 return 0; /* 0dB */ 555} 556EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain); 557 | 547 if (val & TWL6040_HSDACMODE) 548 /* HSDACL in LP mode */ 549 return -8; /* -8dB */ 550 else 551 /* HSDACL in HP mode */ 552 return -1; /* -1dB */ 553 } 554 return 0; /* 0dB */ 555} 556EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain); 557 |
558int twl6040_get_clk_id(struct snd_soc_codec *codec) | 558int twl6040_get_clk_id(struct snd_soc_component *component) |
559{ | 559{ |
560 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 560 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
561 562 return priv->pll_power_mode; 563} 564EXPORT_SYMBOL_GPL(twl6040_get_clk_id); 565 | 561 562 return priv->pll_power_mode; 563} 564EXPORT_SYMBOL_GPL(twl6040_get_clk_id); 565 |
566int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim) | 566int twl6040_get_trim_value(struct snd_soc_component *component, enum twl6040_trim trim) |
567{ 568 if (unlikely(trim >= TWL6040_TRIM_INVAL)) 569 return -EINVAL; 570 | 567{ 568 if (unlikely(trim >= TWL6040_TRIM_INVAL)) 569 return -EINVAL; 570 |
571 return twl6040_read(codec, TWL6040_REG_TRIM1 + trim); | 571 return twl6040_read(component, TWL6040_REG_TRIM1 + trim); |
572} 573EXPORT_SYMBOL_GPL(twl6040_get_trim_value); 574 | 572} 573EXPORT_SYMBOL_GPL(twl6040_get_trim_value); 574 |
575int twl6040_get_hs_step_size(struct snd_soc_codec *codec) | 575int twl6040_get_hs_step_size(struct snd_soc_component *component) |
576{ | 576{ |
577 struct twl6040 *twl6040 = to_twl6040(codec); | 577 struct twl6040 *twl6040 = to_twl6040(component); |
578 579 if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3) 580 /* For ES under ES_1.3 HS step is 2 mV */ 581 return 2; 582 else 583 /* For ES_1.3 HS step is 1 mV */ 584 return 1; 585} --- 238 unchanged lines hidden (view full) --- 824 {"Vibra Right Driver", NULL, "Vibra Right Playback"}, 825 {"Vibra Left Driver", NULL, "Vibra Left Control"}, 826 {"Vibra Right Driver", NULL, "Vibra Right Control"}, 827 828 {"VIBRAL", NULL, "Vibra Left Driver"}, 829 {"VIBRAR", NULL, "Vibra Right Driver"}, 830}; 831 | 578 579 if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3) 580 /* For ES under ES_1.3 HS step is 2 mV */ 581 return 2; 582 else 583 /* For ES_1.3 HS step is 1 mV */ 584 return 1; 585} --- 238 unchanged lines hidden (view full) --- 824 {"Vibra Right Driver", NULL, "Vibra Right Playback"}, 825 {"Vibra Left Driver", NULL, "Vibra Left Control"}, 826 {"Vibra Right Driver", NULL, "Vibra Right Control"}, 827 828 {"VIBRAL", NULL, "Vibra Left Driver"}, 829 {"VIBRAR", NULL, "Vibra Right Driver"}, 830}; 831 |
832static int twl6040_set_bias_level(struct snd_soc_codec *codec, | 832static int twl6040_set_bias_level(struct snd_soc_component *component, |
833 enum snd_soc_bias_level level) 834{ | 833 enum snd_soc_bias_level level) 834{ |
835 struct twl6040 *twl6040 = to_twl6040(codec); 836 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 835 struct twl6040 *twl6040 = to_twl6040(component); 836 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
837 int ret = 0; 838 839 switch (level) { 840 case SND_SOC_BIAS_ON: 841 break; 842 case SND_SOC_BIAS_PREPARE: 843 break; 844 case SND_SOC_BIAS_STANDBY: --- 6 unchanged lines hidden (view full) --- 851 852 ret = twl6040_power(twl6040, 1); 853 if (ret) 854 break; 855 856 priv->codec_powered = 1; 857 858 /* Set external boost GPO */ | 837 int ret = 0; 838 839 switch (level) { 840 case SND_SOC_BIAS_ON: 841 break; 842 case SND_SOC_BIAS_PREPARE: 843 break; 844 case SND_SOC_BIAS_STANDBY: --- 6 unchanged lines hidden (view full) --- 851 852 ret = twl6040_power(twl6040, 1); 853 if (ret) 854 break; 855 856 priv->codec_powered = 1; 857 858 /* Set external boost GPO */ |
859 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); | 859 twl6040_write(component, TWL6040_REG_GPOCTL, 0x02); |
860 break; 861 case SND_SOC_BIAS_OFF: 862 if (!priv->codec_powered) 863 break; 864 865 twl6040_power(twl6040, 0); 866 priv->codec_powered = 0; 867 break; 868 } 869 870 return ret; 871} 872 873static int twl6040_startup(struct snd_pcm_substream *substream, 874 struct snd_soc_dai *dai) 875{ | 860 break; 861 case SND_SOC_BIAS_OFF: 862 if (!priv->codec_powered) 863 break; 864 865 twl6040_power(twl6040, 0); 866 priv->codec_powered = 0; 867 break; 868 } 869 870 return ret; 871} 872 873static int twl6040_startup(struct snd_pcm_substream *substream, 874 struct snd_soc_dai *dai) 875{ |
876 struct snd_soc_codec *codec = dai->codec; 877 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 876 struct snd_soc_component *component = dai->component; 877 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
878 879 snd_pcm_hw_constraint_list(substream->runtime, 0, 880 SNDRV_PCM_HW_PARAM_RATE, 881 &sysclk_constraints[priv->pll_power_mode]); 882 883 return 0; 884} 885 886static int twl6040_hw_params(struct snd_pcm_substream *substream, 887 struct snd_pcm_hw_params *params, 888 struct snd_soc_dai *dai) 889{ | 878 879 snd_pcm_hw_constraint_list(substream->runtime, 0, 880 SNDRV_PCM_HW_PARAM_RATE, 881 &sysclk_constraints[priv->pll_power_mode]); 882 883 return 0; 884} 885 886static int twl6040_hw_params(struct snd_pcm_substream *substream, 887 struct snd_pcm_hw_params *params, 888 struct snd_soc_dai *dai) 889{ |
890 struct snd_soc_codec *codec = dai->codec; 891 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 890 struct snd_soc_component *component = dai->component; 891 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
892 int rate; 893 894 rate = params_rate(params); 895 switch (rate) { 896 case 11250: 897 case 22500: 898 case 44100: 899 case 88200: 900 /* These rates are not supported when HPPLL is in use */ 901 if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) { | 892 int rate; 893 894 rate = params_rate(params); 895 switch (rate) { 896 case 11250: 897 case 22500: 898 case 44100: 899 case 88200: 900 /* These rates are not supported when HPPLL is in use */ 901 if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) { |
902 dev_err(codec->dev, "HPPLL does not support rate %d\n", | 902 dev_err(component->dev, "HPPLL does not support rate %d\n", |
903 rate); 904 return -EINVAL; 905 } 906 priv->sysclk = 17640000; 907 break; 908 case 8000: 909 case 16000: 910 case 32000: 911 case 48000: 912 case 96000: 913 priv->sysclk = 19200000; 914 break; 915 default: | 903 rate); 904 return -EINVAL; 905 } 906 priv->sysclk = 17640000; 907 break; 908 case 8000: 909 case 16000: 910 case 32000: 911 case 48000: 912 case 96000: 913 priv->sysclk = 19200000; 914 break; 915 default: |
916 dev_err(codec->dev, "unsupported rate %d\n", rate); | 916 dev_err(component->dev, "unsupported rate %d\n", rate); |
917 return -EINVAL; 918 } 919 920 return 0; 921} 922 923static int twl6040_prepare(struct snd_pcm_substream *substream, 924 struct snd_soc_dai *dai) 925{ | 917 return -EINVAL; 918 } 919 920 return 0; 921} 922 923static int twl6040_prepare(struct snd_pcm_substream *substream, 924 struct snd_soc_dai *dai) 925{ |
926 struct snd_soc_codec *codec = dai->codec; 927 struct twl6040 *twl6040 = to_twl6040(codec); 928 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 926 struct snd_soc_component *component = dai->component; 927 struct twl6040 *twl6040 = to_twl6040(component); 928 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
929 int ret; 930 931 if (!priv->sysclk) { | 929 int ret; 930 931 if (!priv->sysclk) { |
932 dev_err(codec->dev, | 932 dev_err(component->dev, |
933 "no mclk configured, call set_sysclk() on init\n"); 934 return -EINVAL; 935 } 936 937 ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk); 938 if (ret) { | 933 "no mclk configured, call set_sysclk() on init\n"); 934 return -EINVAL; 935 } 936 937 ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk); 938 if (ret) { |
939 dev_err(codec->dev, "Can not set PLL (%d)\n", ret); | 939 dev_err(component->dev, "Can not set PLL (%d)\n", ret); |
940 return -EPERM; 941 } 942 943 return 0; 944} 945 946static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, 947 int clk_id, unsigned int freq, int dir) 948{ | 940 return -EPERM; 941 } 942 943 return 0; 944} 945 946static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, 947 int clk_id, unsigned int freq, int dir) 948{ |
949 struct snd_soc_codec *codec = codec_dai->codec; 950 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 949 struct snd_soc_component *component = codec_dai->component; 950 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
951 952 switch (clk_id) { 953 case TWL6040_SYSCLK_SEL_LPPLL: 954 case TWL6040_SYSCLK_SEL_HPPLL: 955 priv->pll = clk_id; 956 priv->clk_in = freq; 957 break; 958 default: | 951 952 switch (clk_id) { 953 case TWL6040_SYSCLK_SEL_LPPLL: 954 case TWL6040_SYSCLK_SEL_HPPLL: 955 priv->pll = clk_id; 956 priv->clk_in = freq; 957 break; 958 default: |
959 dev_err(codec->dev, "unknown clk_id %d\n", clk_id); | 959 dev_err(component->dev, "unknown clk_id %d\n", clk_id); |
960 return -EINVAL; 961 } 962 963 return 0; 964} 965 | 960 return -EINVAL; 961 } 962 963 return 0; 964} 965 |
966static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id, | 966static void twl6040_mute_path(struct snd_soc_component *component, enum twl6040_dai_id id, |
967 int mute) 968{ | 967 int mute) 968{ |
969 struct twl6040 *twl6040 = to_twl6040(codec); 970 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 969 struct twl6040 *twl6040 = to_twl6040(component); 970 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
971 int hslctl, hsrctl, earctl; 972 int hflctl, hfrctl; 973 974 switch (id) { 975 case TWL6040_DAI_DL1: | 971 int hslctl, hsrctl, earctl; 972 int hflctl, hfrctl; 973 974 switch (id) { 975 case TWL6040_DAI_DL1: |
976 hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL); 977 hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL); 978 earctl = twl6040_read(codec, TWL6040_REG_EARCTL); | 976 hslctl = twl6040_read(component, TWL6040_REG_HSLCTL); 977 hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL); 978 earctl = twl6040_read(component, TWL6040_REG_EARCTL); |
979 980 if (mute) { 981 /* Power down drivers and DACs */ 982 earctl &= ~0x01; 983 hslctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA); 984 hsrctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA); 985 986 } 987 988 twl6040_reg_write(twl6040, TWL6040_REG_EARCTL, earctl); 989 twl6040_reg_write(twl6040, TWL6040_REG_HSLCTL, hslctl); 990 twl6040_reg_write(twl6040, TWL6040_REG_HSRCTL, hsrctl); 991 priv->dl1_unmuted = !mute; 992 break; 993 case TWL6040_DAI_DL2: | 979 980 if (mute) { 981 /* Power down drivers and DACs */ 982 earctl &= ~0x01; 983 hslctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA); 984 hsrctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA); 985 986 } 987 988 twl6040_reg_write(twl6040, TWL6040_REG_EARCTL, earctl); 989 twl6040_reg_write(twl6040, TWL6040_REG_HSLCTL, hslctl); 990 twl6040_reg_write(twl6040, TWL6040_REG_HSRCTL, hsrctl); 991 priv->dl1_unmuted = !mute; 992 break; 993 case TWL6040_DAI_DL2: |
994 hflctl = twl6040_read(codec, TWL6040_REG_HFLCTL); 995 hfrctl = twl6040_read(codec, TWL6040_REG_HFRCTL); | 994 hflctl = twl6040_read(component, TWL6040_REG_HFLCTL); 995 hfrctl = twl6040_read(component, TWL6040_REG_HFRCTL); |
996 997 if (mute) { 998 /* Power down drivers and DACs */ 999 hflctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA | 1000 TWL6040_HFDRVENA | TWL6040_HFSWENA); 1001 hfrctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA | 1002 TWL6040_HFDRVENA | TWL6040_HFSWENA); 1003 } --- 6 unchanged lines hidden (view full) --- 1010 break; 1011 } 1012} 1013 1014static int twl6040_digital_mute(struct snd_soc_dai *dai, int mute) 1015{ 1016 switch (dai->id) { 1017 case TWL6040_DAI_LEGACY: | 996 997 if (mute) { 998 /* Power down drivers and DACs */ 999 hflctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA | 1000 TWL6040_HFDRVENA | TWL6040_HFSWENA); 1001 hfrctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA | 1002 TWL6040_HFDRVENA | TWL6040_HFSWENA); 1003 } --- 6 unchanged lines hidden (view full) --- 1010 break; 1011 } 1012} 1013 1014static int twl6040_digital_mute(struct snd_soc_dai *dai, int mute) 1015{ 1016 switch (dai->id) { 1017 case TWL6040_DAI_LEGACY: |
1018 twl6040_mute_path(dai->codec, TWL6040_DAI_DL1, mute); 1019 twl6040_mute_path(dai->codec, TWL6040_DAI_DL2, mute); | 1018 twl6040_mute_path(dai->component, TWL6040_DAI_DL1, mute); 1019 twl6040_mute_path(dai->component, TWL6040_DAI_DL2, mute); |
1020 break; 1021 case TWL6040_DAI_DL1: 1022 case TWL6040_DAI_DL2: | 1020 break; 1021 case TWL6040_DAI_DL1: 1022 case TWL6040_DAI_DL2: |
1023 twl6040_mute_path(dai->codec, dai->id, mute); | 1023 twl6040_mute_path(dai->component, dai->id, mute); |
1024 break; 1025 default: 1026 break; 1027 } 1028 1029 return 0; 1030} 1031 --- 70 unchanged lines hidden (view full) --- 1102 .channels_max = 1, 1103 .rates = SNDRV_PCM_RATE_CONTINUOUS, 1104 .formats = TWL6040_FORMATS, 1105 }, 1106 .ops = &twl6040_dai_ops, 1107}, 1108}; 1109 | 1024 break; 1025 default: 1026 break; 1027 } 1028 1029 return 0; 1030} 1031 --- 70 unchanged lines hidden (view full) --- 1102 .channels_max = 1, 1103 .rates = SNDRV_PCM_RATE_CONTINUOUS, 1104 .formats = TWL6040_FORMATS, 1105 }, 1106 .ops = &twl6040_dai_ops, 1107}, 1108}; 1109 |
1110static int twl6040_probe(struct snd_soc_codec *codec) | 1110static int twl6040_probe(struct snd_soc_component *component) |
1111{ 1112 struct twl6040_data *priv; | 1111{ 1112 struct twl6040_data *priv; |
1113 struct platform_device *pdev = to_platform_device(codec->dev); | 1113 struct platform_device *pdev = to_platform_device(component->dev); |
1114 int ret = 0; 1115 | 1114 int ret = 0; 1115 |
1116 priv = devm_kzalloc(codec->dev, sizeof(*priv), GFP_KERNEL); | 1116 priv = devm_kzalloc(component->dev, sizeof(*priv), GFP_KERNEL); |
1117 if (priv == NULL) 1118 return -ENOMEM; 1119 | 1117 if (priv == NULL) 1118 return -ENOMEM; 1119 |
1120 snd_soc_codec_set_drvdata(codec, priv); | 1120 snd_soc_component_set_drvdata(component, priv); |
1121 | 1121 |
1122 priv->codec = codec; | 1122 priv->component = component; |
1123 1124 priv->plug_irq = platform_get_irq(pdev, 0); 1125 if (priv->plug_irq < 0) { | 1123 1124 priv->plug_irq = platform_get_irq(pdev, 0); 1125 if (priv->plug_irq < 0) { |
1126 dev_err(codec->dev, "invalid irq: %d\n", priv->plug_irq); | 1126 dev_err(component->dev, "invalid irq: %d\n", priv->plug_irq); |
1127 return priv->plug_irq; 1128 } 1129 1130 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); 1131 1132 mutex_init(&priv->mutex); 1133 1134 ret = request_threaded_irq(priv->plug_irq, NULL, 1135 twl6040_audio_handler, 1136 IRQF_NO_SUSPEND | IRQF_ONESHOT, | 1127 return priv->plug_irq; 1128 } 1129 1130 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); 1131 1132 mutex_init(&priv->mutex); 1133 1134 ret = request_threaded_irq(priv->plug_irq, NULL, 1135 twl6040_audio_handler, 1136 IRQF_NO_SUSPEND | IRQF_ONESHOT, |
1137 "twl6040_irq_plug", codec); | 1137 "twl6040_irq_plug", component); |
1138 if (ret) { | 1138 if (ret) { |
1139 dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret); | 1139 dev_err(component->dev, "PLUG IRQ request failed: %d\n", ret); |
1140 return ret; 1141 } 1142 | 1140 return ret; 1141 } 1142 |
1143 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); 1144 twl6040_init_chip(codec); | 1143 snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); 1144 twl6040_init_chip(component); |
1145 1146 return 0; 1147} 1148 | 1145 1146 return 0; 1147} 1148 |
1149static int twl6040_remove(struct snd_soc_codec *codec) | 1149static void twl6040_remove(struct snd_soc_component *component) |
1150{ | 1150{ |
1151 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 1151 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); |
1152 | 1152 |
1153 free_irq(priv->plug_irq, codec); 1154 1155 return 0; | 1153 free_irq(priv->plug_irq, component); |
1156} 1157 | 1154} 1155 |
1158static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = { 1159 .probe = twl6040_probe, 1160 .remove = twl6040_remove, 1161 .read = twl6040_read, 1162 .write = twl6040_write, 1163 .set_bias_level = twl6040_set_bias_level, 1164 .suspend_bias_off = true, 1165 .ignore_pmdown_time = true, 1166 1167 .component_driver = { 1168 .controls = twl6040_snd_controls, 1169 .num_controls = ARRAY_SIZE(twl6040_snd_controls), 1170 .dapm_widgets = twl6040_dapm_widgets, 1171 .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), 1172 .dapm_routes = intercon, 1173 .num_dapm_routes = ARRAY_SIZE(intercon), 1174 }, | 1156static const struct snd_soc_component_driver soc_component_dev_twl6040 = { 1157 .probe = twl6040_probe, 1158 .remove = twl6040_remove, 1159 .read = twl6040_read, 1160 .remove = twl6040_remove, 1161 .set_bias_level = twl6040_set_bias_level, 1162 .controls = twl6040_snd_controls, 1163 .num_controls = ARRAY_SIZE(twl6040_snd_controls), 1164 .dapm_widgets = twl6040_dapm_widgets, 1165 .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), 1166 .dapm_routes = intercon, 1167 .num_dapm_routes = ARRAY_SIZE(intercon), 1168 .suspend_bias_off = 1, 1169 .idle_bias_on = 1, 1170 .endianness = 1, 1171 .non_legacy_dai_naming = 1, |
1175}; 1176 1177static int twl6040_codec_probe(struct platform_device *pdev) 1178{ | 1172}; 1173 1174static int twl6040_codec_probe(struct platform_device *pdev) 1175{ |
1179 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040, | 1176 return devm_snd_soc_register_component(&pdev->dev, 1177 &soc_component_dev_twl6040, |
1180 twl6040_dai, ARRAY_SIZE(twl6040_dai)); 1181} 1182 | 1178 twl6040_dai, ARRAY_SIZE(twl6040_dai)); 1179} 1180 |
1183static int twl6040_codec_remove(struct platform_device *pdev) 1184{ 1185 snd_soc_unregister_codec(&pdev->dev); 1186 return 0; 1187} 1188 | |
1189static struct platform_driver twl6040_codec_driver = { 1190 .driver = { 1191 .name = "twl6040-codec", 1192 }, 1193 .probe = twl6040_codec_probe, | 1181static struct platform_driver twl6040_codec_driver = { 1182 .driver = { 1183 .name = "twl6040-codec", 1184 }, 1185 .probe = twl6040_codec_probe, |
1194 .remove = twl6040_codec_remove, | |
1195}; 1196 1197module_platform_driver(twl6040_codec_driver); 1198 1199MODULE_DESCRIPTION("ASoC TWL6040 codec driver"); 1200MODULE_AUTHOR("Misael Lopez Cruz"); 1201MODULE_LICENSE("GPL"); | 1186}; 1187 1188module_platform_driver(twl6040_codec_driver); 1189 1190MODULE_DESCRIPTION("ASoC TWL6040 codec driver"); 1191MODULE_AUTHOR("Misael Lopez Cruz"); 1192MODULE_LICENSE("GPL"); |