diff options
author | Mark Brown <broonie@linaro.org> | 2013-11-08 05:43:39 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-11-08 05:43:39 -0500 |
commit | 32b7fdfefa0e182754f683cc7213fddce1db64d0 (patch) | |
tree | 5e1d40185738a5e3edd753fed1c79df76e04edb5 /sound | |
parent | abdf150adea396c123032096684ab746adcd2664 (diff) | |
parent | 4d208ca429ad424595fd08c0cca323605ebfc38b (diff) |
Merge remote-tracking branch 'asoc/topic/tlv320aic32x4' into asoc-next
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/tlv320aic32x4.c | 101 |
1 files changed, 30 insertions, 71 deletions
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 2ed57d4aa445..18cdcca9014c 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -60,9 +60,8 @@ struct aic32x4_rate_divs { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | struct aic32x4_priv { | 62 | struct aic32x4_priv { |
63 | struct regmap *regmap; | ||
63 | u32 sysclk; | 64 | u32 sysclk; |
64 | u8 page_no; | ||
65 | void *control_data; | ||
66 | u32 power_cfg; | 65 | u32 power_cfg; |
67 | u32 micpga_routing; | 66 | u32 micpga_routing; |
68 | bool swapdacs; | 67 | bool swapdacs; |
@@ -262,67 +261,25 @@ static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = { | |||
262 | {"Right ADC", NULL, "Right Input Mixer"}, | 261 | {"Right ADC", NULL, "Right Input Mixer"}, |
263 | }; | 262 | }; |
264 | 263 | ||
265 | static inline int aic32x4_change_page(struct snd_soc_codec *codec, | 264 | static const struct regmap_range_cfg aic32x4_regmap_pages[] = { |
266 | unsigned int new_page) | 265 | { |
267 | { | 266 | .selector_reg = 0, |
268 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 267 | .selector_mask = 0xff, |
269 | u8 data[2]; | 268 | .window_start = 0, |
270 | int ret; | 269 | .window_len = 128, |
271 | 270 | .range_min = AIC32X4_PAGE1, | |
272 | data[0] = 0x00; | 271 | .range_max = AIC32X4_PAGE1 + 127, |
273 | data[1] = new_page & 0xff; | 272 | }, |
274 | 273 | }; | |
275 | ret = codec->hw_write(codec->control_data, data, 2); | ||
276 | if (ret == 2) { | ||
277 | aic32x4->page_no = new_page; | ||
278 | return 0; | ||
279 | } else { | ||
280 | return ret; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | static int aic32x4_write(struct snd_soc_codec *codec, unsigned int reg, | ||
285 | unsigned int val) | ||
286 | { | ||
287 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | ||
288 | unsigned int page = reg / 128; | ||
289 | unsigned int fixed_reg = reg % 128; | ||
290 | u8 data[2]; | ||
291 | int ret; | ||
292 | |||
293 | /* A write to AIC32X4_PSEL is really a non-explicit page change */ | ||
294 | if (reg == AIC32X4_PSEL) | ||
295 | return aic32x4_change_page(codec, val); | ||
296 | |||
297 | if (aic32x4->page_no != page) { | ||
298 | ret = aic32x4_change_page(codec, page); | ||
299 | if (ret != 0) | ||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | data[0] = fixed_reg & 0xff; | ||
304 | data[1] = val & 0xff; | ||
305 | |||
306 | if (codec->hw_write(codec->control_data, data, 2) == 2) | ||
307 | return 0; | ||
308 | else | ||
309 | return -EIO; | ||
310 | } | ||
311 | 274 | ||
312 | static unsigned int aic32x4_read(struct snd_soc_codec *codec, unsigned int reg) | 275 | static const struct regmap_config aic32x4_regmap = { |
313 | { | 276 | .reg_bits = 8, |
314 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 277 | .val_bits = 8, |
315 | unsigned int page = reg / 128; | ||
316 | unsigned int fixed_reg = reg % 128; | ||
317 | int ret; | ||
318 | 278 | ||
319 | if (aic32x4->page_no != page) { | 279 | .max_register = AIC32X4_RMICPGAVOL, |
320 | ret = aic32x4_change_page(codec, page); | 280 | .ranges = aic32x4_regmap_pages, |
321 | if (ret != 0) | 281 | .num_ranges = ARRAY_SIZE(aic32x4_regmap_pages), |
322 | return ret; | 282 | }; |
323 | } | ||
324 | return i2c_smbus_read_byte_data(codec->control_data, fixed_reg & 0xff); | ||
325 | } | ||
326 | 283 | ||
327 | static inline int aic32x4_get_divs(int mclk, int rate) | 284 | static inline int aic32x4_get_divs(int mclk, int rate) |
328 | { | 285 | { |
@@ -617,16 +574,10 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
617 | { | 574 | { |
618 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 575 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); |
619 | u32 tmp_reg; | 576 | u32 tmp_reg; |
620 | int ret; | ||
621 | 577 | ||
622 | codec->hw_write = (hw_write_t) i2c_master_send; | 578 | snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); |
623 | codec->control_data = aic32x4->control_data; | ||
624 | 579 | ||
625 | if (aic32x4->rstn_gpio >= 0) { | 580 | if (aic32x4->rstn_gpio >= 0) { |
626 | ret = devm_gpio_request_one(codec->dev, aic32x4->rstn_gpio, | ||
627 | GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); | ||
628 | if (ret != 0) | ||
629 | return ret; | ||
630 | ndelay(10); | 581 | ndelay(10); |
631 | gpio_set_value(aic32x4->rstn_gpio, 1); | 582 | gpio_set_value(aic32x4->rstn_gpio, 1); |
632 | } | 583 | } |
@@ -692,8 +643,6 @@ static int aic32x4_remove(struct snd_soc_codec *codec) | |||
692 | } | 643 | } |
693 | 644 | ||
694 | static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { | 645 | static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { |
695 | .read = aic32x4_read, | ||
696 | .write = aic32x4_write, | ||
697 | .probe = aic32x4_probe, | 646 | .probe = aic32x4_probe, |
698 | .remove = aic32x4_remove, | 647 | .remove = aic32x4_remove, |
699 | .suspend = aic32x4_suspend, | 648 | .suspend = aic32x4_suspend, |
@@ -720,7 +669,10 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, | |||
720 | if (aic32x4 == NULL) | 669 | if (aic32x4 == NULL) |
721 | return -ENOMEM; | 670 | return -ENOMEM; |
722 | 671 | ||
723 | aic32x4->control_data = i2c; | 672 | aic32x4->regmap = devm_regmap_init_i2c(i2c, &aic32x4_regmap); |
673 | if (IS_ERR(aic32x4->regmap)) | ||
674 | return PTR_ERR(aic32x4->regmap); | ||
675 | |||
724 | i2c_set_clientdata(i2c, aic32x4); | 676 | i2c_set_clientdata(i2c, aic32x4); |
725 | 677 | ||
726 | if (pdata) { | 678 | if (pdata) { |
@@ -735,6 +687,13 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, | |||
735 | aic32x4->rstn_gpio = -1; | 687 | aic32x4->rstn_gpio = -1; |
736 | } | 688 | } |
737 | 689 | ||
690 | if (aic32x4->rstn_gpio >= 0) { | ||
691 | ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio, | ||
692 | GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); | ||
693 | if (ret != 0) | ||
694 | return ret; | ||
695 | } | ||
696 | |||
738 | ret = snd_soc_register_codec(&i2c->dev, | 697 | ret = snd_soc_register_codec(&i2c->dev, |
739 | &soc_codec_dev_aic32x4, &aic32x4_dai, 1); | 698 | &soc_codec_dev_aic32x4, &aic32x4_dai, 1); |
740 | return ret; | 699 | return ret; |