aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8523.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-07-10 18:12:01 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-03 11:59:16 -0400
commit8d50e447d19fec64adebeef55f2b60d695435412 (patch)
treeaac4234db113cf40abc4c7779ddecb76d7e0946b /sound/soc/codecs/wm8523.c
parentafa2f1066e7288a9e4f8e3fda277da245219dffc (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.c98
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
65static int wm8523_volatile(unsigned int reg) 65static 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
76static 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
96static int wm8523_reset(struct snd_soc_codec *codec) 76static 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
101static 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 = &reg;
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
130static 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
143static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0); 81static 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};
544EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523); 482EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523);
545 483
546static int wm8523_register(struct wm8523_priv *wm8523) 484static 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
690static __devexit int wm8523_i2c_remove(struct i2c_client *client) 634static __devexit int wm8523_i2c_remove(struct i2c_client *client)