diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-07-10 18:12:01 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-08-03 11:59:16 -0400 |
commit | 8d50e447d19fec64adebeef55f2b60d695435412 (patch) | |
tree | aac4234db113cf40abc4c7779ddecb76d7e0946b /sound/soc/codecs/wm8523.c | |
parent | afa2f1066e7288a9e4f8e3fda277da245219dffc (diff) |
ASoC: Factor out I/O for Wolfson 8 bit data 16 bit register CODECs
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8523.c')
-rw-r--r-- | sound/soc/codecs/wm8523.c | 98 |
1 files changed, 21 insertions, 77 deletions
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 3b499ae7ce6c..25870a4652fb 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c | |||
@@ -62,7 +62,7 @@ static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = { | |||
62 | 0x0000, /* R8 - ZERO_DETECT */ | 62 | 0x0000, /* R8 - ZERO_DETECT */ |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static int wm8523_volatile(unsigned int reg) | 65 | static int wm8523_volatile_register(unsigned int reg) |
66 | { | 66 | { |
67 | switch (reg) { | 67 | switch (reg) { |
68 | case WM8523_DEVICE_ID: | 68 | case WM8523_DEVICE_ID: |
@@ -73,71 +73,9 @@ static int wm8523_volatile(unsigned int reg) | |||
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | static int wm8523_write(struct snd_soc_codec *codec, unsigned int reg, | ||
77 | unsigned int value) | ||
78 | { | ||
79 | struct wm8523_priv *wm8523 = codec->private_data; | ||
80 | u8 data[3]; | ||
81 | |||
82 | BUG_ON(reg > WM8523_MAX_REGISTER); | ||
83 | |||
84 | data[0] = reg; | ||
85 | data[1] = (value >> 8) & 0x00ff; | ||
86 | data[2] = value & 0x00ff; | ||
87 | |||
88 | if (!wm8523_volatile(reg)) | ||
89 | wm8523->reg_cache[reg] = value; | ||
90 | if (codec->hw_write(codec->control_data, data, 3) == 3) | ||
91 | return 0; | ||
92 | else | ||
93 | return -EIO; | ||
94 | } | ||
95 | |||
96 | static int wm8523_reset(struct snd_soc_codec *codec) | 76 | static int wm8523_reset(struct snd_soc_codec *codec) |
97 | { | 77 | { |
98 | return wm8523_write(codec, WM8523_DEVICE_ID, 0); | 78 | return snd_soc_write(codec, WM8523_DEVICE_ID, 0); |
99 | } | ||
100 | |||
101 | static unsigned int wm8523_read_hw(struct snd_soc_codec *codec, u8 reg) | ||
102 | { | ||
103 | struct i2c_msg xfer[2]; | ||
104 | u16 data; | ||
105 | int ret; | ||
106 | struct i2c_client *i2c = codec->control_data; | ||
107 | |||
108 | /* Write register */ | ||
109 | xfer[0].addr = i2c->addr; | ||
110 | xfer[0].flags = 0; | ||
111 | xfer[0].len = 1; | ||
112 | xfer[0].buf = ® | ||
113 | |||
114 | /* Read data */ | ||
115 | xfer[1].addr = i2c->addr; | ||
116 | xfer[1].flags = I2C_M_RD; | ||
117 | xfer[1].len = 2; | ||
118 | xfer[1].buf = (u8 *)&data; | ||
119 | |||
120 | ret = i2c_transfer(i2c->adapter, xfer, 2); | ||
121 | if (ret != 2) { | ||
122 | dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | return (data >> 8) | ((data & 0xff) << 8); | ||
127 | } | ||
128 | |||
129 | |||
130 | static unsigned int wm8523_read(struct snd_soc_codec *codec, | ||
131 | unsigned int reg) | ||
132 | { | ||
133 | u16 *reg_cache = codec->reg_cache; | ||
134 | |||
135 | BUG_ON(reg > WM8523_MAX_REGISTER); | ||
136 | |||
137 | if (wm8523_volatile(reg)) | ||
138 | return wm8523_read_hw(codec, reg); | ||
139 | else | ||
140 | return reg_cache[reg]; | ||
141 | } | 79 | } |
142 | 80 | ||
143 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0); | 81 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0); |
@@ -228,8 +166,8 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream, | |||
228 | struct snd_soc_codec *codec = socdev->card->codec; | 166 | struct snd_soc_codec *codec = socdev->card->codec; |
229 | struct wm8523_priv *wm8523 = codec->private_data; | 167 | struct wm8523_priv *wm8523 = codec->private_data; |
230 | int i; | 168 | int i; |
231 | u16 aifctrl1 = wm8523_read(codec, WM8523_AIF_CTRL1); | 169 | u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1); |
232 | u16 aifctrl2 = wm8523_read(codec, WM8523_AIF_CTRL2); | 170 | u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2); |
233 | 171 | ||
234 | /* Find a supported LRCLK ratio */ | 172 | /* Find a supported LRCLK ratio */ |
235 | for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { | 173 | for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { |
@@ -263,8 +201,8 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream, | |||
263 | break; | 201 | break; |
264 | } | 202 | } |
265 | 203 | ||
266 | wm8523_write(codec, WM8523_AIF_CTRL1, aifctrl1); | 204 | snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1); |
267 | wm8523_write(codec, WM8523_AIF_CTRL2, aifctrl2); | 205 | snd_soc_write(codec, WM8523_AIF_CTRL2, aifctrl2); |
268 | 206 | ||
269 | return 0; | 207 | return 0; |
270 | } | 208 | } |
@@ -322,7 +260,7 @@ static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
322 | unsigned int fmt) | 260 | unsigned int fmt) |
323 | { | 261 | { |
324 | struct snd_soc_codec *codec = codec_dai->codec; | 262 | struct snd_soc_codec *codec = codec_dai->codec; |
325 | u16 aifctrl1 = wm8523_read(codec, WM8523_AIF_CTRL1); | 263 | u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1); |
326 | 264 | ||
327 | aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK | | 265 | aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK | |
328 | WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK); | 266 | WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK); |
@@ -372,7 +310,7 @@ static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
372 | return -EINVAL; | 310 | return -EINVAL; |
373 | } | 311 | } |
374 | 312 | ||
375 | wm8523_write(codec, WM8523_AIF_CTRL1, aifctrl1); | 313 | snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1); |
376 | 314 | ||
377 | return 0; | 315 | return 0; |
378 | } | 316 | } |
@@ -411,7 +349,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, | |||
411 | /* Sync back default/cached values */ | 349 | /* Sync back default/cached values */ |
412 | for (i = WM8523_AIF_CTRL1; | 350 | for (i = WM8523_AIF_CTRL1; |
413 | i < WM8523_MAX_REGISTER; i++) | 351 | i < WM8523_MAX_REGISTER; i++) |
414 | wm8523_write(codec, i, wm8523->reg_cache[i]); | 352 | snd_soc_write(codec, i, wm8523->reg_cache[i]); |
415 | 353 | ||
416 | 354 | ||
417 | msleep(100); | 355 | msleep(100); |
@@ -543,7 +481,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8523 = { | |||
543 | }; | 481 | }; |
544 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523); | 482 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523); |
545 | 483 | ||
546 | static int wm8523_register(struct wm8523_priv *wm8523) | 484 | static int wm8523_register(struct wm8523_priv *wm8523, |
485 | enum snd_soc_control_type control) | ||
547 | { | 486 | { |
548 | int ret; | 487 | int ret; |
549 | struct snd_soc_codec *codec = &wm8523->codec; | 488 | struct snd_soc_codec *codec = &wm8523->codec; |
@@ -561,14 +500,13 @@ static int wm8523_register(struct wm8523_priv *wm8523) | |||
561 | codec->private_data = wm8523; | 500 | codec->private_data = wm8523; |
562 | codec->name = "WM8523"; | 501 | codec->name = "WM8523"; |
563 | codec->owner = THIS_MODULE; | 502 | codec->owner = THIS_MODULE; |
564 | codec->read = wm8523_read; | ||
565 | codec->write = wm8523_write; | ||
566 | codec->bias_level = SND_SOC_BIAS_OFF; | 503 | codec->bias_level = SND_SOC_BIAS_OFF; |
567 | codec->set_bias_level = wm8523_set_bias_level; | 504 | codec->set_bias_level = wm8523_set_bias_level; |
568 | codec->dai = &wm8523_dai; | 505 | codec->dai = &wm8523_dai; |
569 | codec->num_dai = 1; | 506 | codec->num_dai = 1; |
570 | codec->reg_cache_size = WM8523_REGISTER_COUNT; | 507 | codec->reg_cache_size = WM8523_REGISTER_COUNT; |
571 | codec->reg_cache = &wm8523->reg_cache; | 508 | codec->reg_cache = &wm8523->reg_cache; |
509 | codec->volatile_register = wm8523_volatile_register; | ||
572 | 510 | ||
573 | wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; | 511 | wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; |
574 | wm8523->rate_constraint.count = | 512 | wm8523->rate_constraint.count = |
@@ -576,6 +514,12 @@ static int wm8523_register(struct wm8523_priv *wm8523) | |||
576 | 514 | ||
577 | memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg)); | 515 | memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg)); |
578 | 516 | ||
517 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); | ||
518 | if (ret != 0) { | ||
519 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
520 | goto err; | ||
521 | } | ||
522 | |||
579 | for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) | 523 | for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) |
580 | wm8523->supplies[i].supply = wm8523_supply_names[i]; | 524 | wm8523->supplies[i].supply = wm8523_supply_names[i]; |
581 | 525 | ||
@@ -593,7 +537,7 @@ static int wm8523_register(struct wm8523_priv *wm8523) | |||
593 | goto err_get; | 537 | goto err_get; |
594 | } | 538 | } |
595 | 539 | ||
596 | ret = wm8523_read(codec, WM8523_DEVICE_ID); | 540 | ret = snd_soc_read(codec, WM8523_DEVICE_ID); |
597 | if (ret < 0) { | 541 | if (ret < 0) { |
598 | dev_err(codec->dev, "Failed to read ID register\n"); | 542 | dev_err(codec->dev, "Failed to read ID register\n"); |
599 | goto err_enable; | 543 | goto err_enable; |
@@ -604,7 +548,7 @@ static int wm8523_register(struct wm8523_priv *wm8523) | |||
604 | goto err_enable; | 548 | goto err_enable; |
605 | } | 549 | } |
606 | 550 | ||
607 | ret = wm8523_read(codec, WM8523_REVISION); | 551 | ret = snd_soc_read(codec, WM8523_REVISION); |
608 | if (ret < 0) { | 552 | if (ret < 0) { |
609 | dev_err(codec->dev, "Failed to read revision register\n"); | 553 | dev_err(codec->dev, "Failed to read revision register\n"); |
610 | goto err_enable; | 554 | goto err_enable; |
@@ -684,7 +628,7 @@ static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, | |||
684 | 628 | ||
685 | codec->dev = &i2c->dev; | 629 | codec->dev = &i2c->dev; |
686 | 630 | ||
687 | return wm8523_register(wm8523); | 631 | return wm8523_register(wm8523, SND_SOC_I2C); |
688 | } | 632 | } |
689 | 633 | ||
690 | static __devexit int wm8523_i2c_remove(struct i2c_client *client) | 634 | static __devexit int wm8523_i2c_remove(struct i2c_client *client) |