diff options
Diffstat (limited to 'sound/soc/codecs/88pm860x-codec.c')
-rw-r--r-- | sound/soc/codecs/88pm860x-codec.c | 78 |
1 files changed, 16 insertions, 62 deletions
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 8af04343cc1a..75d0ad5d2dcb 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/mfd/88pm860x.h> | 16 | #include <linux/mfd/88pm860x.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/regmap.h> | ||
19 | #include <sound/core.h> | 20 | #include <sound/core.h> |
20 | #include <sound/pcm.h> | 21 | #include <sound/pcm.h> |
21 | #include <sound/pcm_params.h> | 22 | #include <sound/pcm_params.h> |
@@ -140,6 +141,7 @@ struct pm860x_priv { | |||
140 | unsigned int filter; | 141 | unsigned int filter; |
141 | struct snd_soc_codec *codec; | 142 | struct snd_soc_codec *codec; |
142 | struct i2c_client *i2c; | 143 | struct i2c_client *i2c; |
144 | struct regmap *regmap; | ||
143 | struct pm860x_chip *chip; | 145 | struct pm860x_chip *chip; |
144 | struct pm860x_det det; | 146 | struct pm860x_det det; |
145 | 147 | ||
@@ -269,48 +271,6 @@ static struct st_gain st_table[] = { | |||
269 | { -86, 29, 0}, { -56, 30, 0}, { -28, 31, 0}, { 0, 0, 0}, | 271 | { -86, 29, 0}, { -56, 30, 0}, { -28, 31, 0}, { 0, 0, 0}, |
270 | }; | 272 | }; |
271 | 273 | ||
272 | static int pm860x_volatile(unsigned int reg) | ||
273 | { | ||
274 | BUG_ON(reg >= REG_CACHE_SIZE); | ||
275 | |||
276 | switch (reg) { | ||
277 | case PM860X_AUDIO_SUPPLIES_2: | ||
278 | return 1; | ||
279 | } | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static unsigned int pm860x_read_reg_cache(struct snd_soc_codec *codec, | ||
285 | unsigned int reg) | ||
286 | { | ||
287 | unsigned char *cache = codec->reg_cache; | ||
288 | |||
289 | BUG_ON(reg >= REG_CACHE_SIZE); | ||
290 | |||
291 | if (pm860x_volatile(reg)) | ||
292 | return cache[reg]; | ||
293 | |||
294 | reg += REG_CACHE_BASE; | ||
295 | |||
296 | return pm860x_reg_read(codec->control_data, reg); | ||
297 | } | ||
298 | |||
299 | static int pm860x_write_reg_cache(struct snd_soc_codec *codec, | ||
300 | unsigned int reg, unsigned int value) | ||
301 | { | ||
302 | unsigned char *cache = codec->reg_cache; | ||
303 | |||
304 | BUG_ON(reg >= REG_CACHE_SIZE); | ||
305 | |||
306 | if (!pm860x_volatile(reg)) | ||
307 | cache[reg] = (unsigned char)value; | ||
308 | |||
309 | reg += REG_CACHE_BASE; | ||
310 | |||
311 | return pm860x_reg_write(codec->control_data, reg, value); | ||
312 | } | ||
313 | |||
314 | static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol, | 274 | static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol, |
315 | struct snd_ctl_elem_value *ucontrol) | 275 | struct snd_ctl_elem_value *ucontrol) |
316 | { | 276 | { |
@@ -349,6 +309,9 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol, | |||
349 | val = ucontrol->value.integer.value[0]; | 309 | val = ucontrol->value.integer.value[0]; |
350 | val2 = ucontrol->value.integer.value[1]; | 310 | val2 = ucontrol->value.integer.value[1]; |
351 | 311 | ||
312 | if (val >= ARRAY_SIZE(st_table) || val2 >= ARRAY_SIZE(st_table)) | ||
313 | return -EINVAL; | ||
314 | |||
352 | err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m); | 315 | err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m); |
353 | if (err < 0) | 316 | if (err < 0) |
354 | return err; | 317 | return err; |
@@ -1166,6 +1129,7 @@ static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1166 | static int pm860x_set_bias_level(struct snd_soc_codec *codec, | 1129 | static int pm860x_set_bias_level(struct snd_soc_codec *codec, |
1167 | enum snd_soc_bias_level level) | 1130 | enum snd_soc_bias_level level) |
1168 | { | 1131 | { |
1132 | struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec); | ||
1169 | int data; | 1133 | int data; |
1170 | 1134 | ||
1171 | switch (level) { | 1135 | switch (level) { |
@@ -1179,17 +1143,17 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, | |||
1179 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 1143 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
1180 | /* Enable Audio PLL & Audio section */ | 1144 | /* Enable Audio PLL & Audio section */ |
1181 | data = AUDIO_PLL | AUDIO_SECTION_ON; | 1145 | data = AUDIO_PLL | AUDIO_SECTION_ON; |
1182 | pm860x_reg_write(codec->control_data, REG_MISC2, data); | 1146 | pm860x_reg_write(pm860x->i2c, REG_MISC2, data); |
1183 | udelay(300); | 1147 | udelay(300); |
1184 | data = AUDIO_PLL | AUDIO_SECTION_RESET | 1148 | data = AUDIO_PLL | AUDIO_SECTION_RESET |
1185 | | AUDIO_SECTION_ON; | 1149 | | AUDIO_SECTION_ON; |
1186 | pm860x_reg_write(codec->control_data, REG_MISC2, data); | 1150 | pm860x_reg_write(pm860x->i2c, REG_MISC2, data); |
1187 | } | 1151 | } |
1188 | break; | 1152 | break; |
1189 | 1153 | ||
1190 | case SND_SOC_BIAS_OFF: | 1154 | case SND_SOC_BIAS_OFF: |
1191 | data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON; | 1155 | data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON; |
1192 | pm860x_set_bits(codec->control_data, REG_MISC2, data, 0); | 1156 | pm860x_set_bits(pm860x->i2c, REG_MISC2, data, 0); |
1193 | break; | 1157 | break; |
1194 | } | 1158 | } |
1195 | codec->dapm.bias_level = level; | 1159 | codec->dapm.bias_level = level; |
@@ -1319,17 +1283,17 @@ int pm860x_hs_jack_detect(struct snd_soc_codec *codec, | |||
1319 | pm860x->det.lo_shrt = lo_shrt; | 1283 | pm860x->det.lo_shrt = lo_shrt; |
1320 | 1284 | ||
1321 | if (det & SND_JACK_HEADPHONE) | 1285 | if (det & SND_JACK_HEADPHONE) |
1322 | pm860x_set_bits(codec->control_data, REG_HS_DET, | 1286 | pm860x_set_bits(pm860x->i2c, REG_HS_DET, |
1323 | EN_HS_DET, EN_HS_DET); | 1287 | EN_HS_DET, EN_HS_DET); |
1324 | /* headset short detect */ | 1288 | /* headset short detect */ |
1325 | if (hs_shrt) { | 1289 | if (hs_shrt) { |
1326 | data = CLR_SHORT_HS2 | CLR_SHORT_HS1; | 1290 | data = CLR_SHORT_HS2 | CLR_SHORT_HS1; |
1327 | pm860x_set_bits(codec->control_data, REG_SHORTS, data, data); | 1291 | pm860x_set_bits(pm860x->i2c, REG_SHORTS, data, data); |
1328 | } | 1292 | } |
1329 | /* Lineout short detect */ | 1293 | /* Lineout short detect */ |
1330 | if (lo_shrt) { | 1294 | if (lo_shrt) { |
1331 | data = CLR_SHORT_LO2 | CLR_SHORT_LO1; | 1295 | data = CLR_SHORT_LO2 | CLR_SHORT_LO1; |
1332 | pm860x_set_bits(codec->control_data, REG_SHORTS, data, data); | 1296 | pm860x_set_bits(pm860x->i2c, REG_SHORTS, data, data); |
1333 | } | 1297 | } |
1334 | 1298 | ||
1335 | /* sync status */ | 1299 | /* sync status */ |
@@ -1347,7 +1311,7 @@ int pm860x_mic_jack_detect(struct snd_soc_codec *codec, | |||
1347 | pm860x->det.mic_det = det; | 1311 | pm860x->det.mic_det = det; |
1348 | 1312 | ||
1349 | if (det & SND_JACK_MICROPHONE) | 1313 | if (det & SND_JACK_MICROPHONE) |
1350 | pm860x_set_bits(codec->control_data, REG_MIC_DET, | 1314 | pm860x_set_bits(pm860x->i2c, REG_MIC_DET, |
1351 | MICDET_MASK, MICDET_MASK); | 1315 | MICDET_MASK, MICDET_MASK); |
1352 | 1316 | ||
1353 | /* sync status */ | 1317 | /* sync status */ |
@@ -1363,7 +1327,7 @@ static int pm860x_probe(struct snd_soc_codec *codec) | |||
1363 | 1327 | ||
1364 | pm860x->codec = codec; | 1328 | pm860x->codec = codec; |
1365 | 1329 | ||
1366 | codec->control_data = pm860x->i2c; | 1330 | codec->control_data = pm860x->regmap; |
1367 | 1331 | ||
1368 | for (i = 0; i < 4; i++) { | 1332 | for (i = 0; i < 4; i++) { |
1369 | ret = request_threaded_irq(pm860x->irq[i], NULL, | 1333 | ret = request_threaded_irq(pm860x->irq[i], NULL, |
@@ -1377,14 +1341,6 @@ static int pm860x_probe(struct snd_soc_codec *codec) | |||
1377 | 1341 | ||
1378 | pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1342 | pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1379 | 1343 | ||
1380 | ret = pm860x_bulk_read(codec->control_data, REG_CACHE_BASE, | ||
1381 | REG_CACHE_SIZE, codec->reg_cache); | ||
1382 | if (ret < 0) { | ||
1383 | dev_err(codec->dev, "Failed to fill register cache: %d\n", | ||
1384 | ret); | ||
1385 | goto out; | ||
1386 | } | ||
1387 | |||
1388 | return 0; | 1344 | return 0; |
1389 | 1345 | ||
1390 | out: | 1346 | out: |
@@ -1407,10 +1363,6 @@ static int pm860x_remove(struct snd_soc_codec *codec) | |||
1407 | static struct snd_soc_codec_driver soc_codec_dev_pm860x = { | 1363 | static struct snd_soc_codec_driver soc_codec_dev_pm860x = { |
1408 | .probe = pm860x_probe, | 1364 | .probe = pm860x_probe, |
1409 | .remove = pm860x_remove, | 1365 | .remove = pm860x_remove, |
1410 | .read = pm860x_read_reg_cache, | ||
1411 | .write = pm860x_write_reg_cache, | ||
1412 | .reg_cache_size = REG_CACHE_SIZE, | ||
1413 | .reg_word_size = sizeof(u8), | ||
1414 | .set_bias_level = pm860x_set_bias_level, | 1366 | .set_bias_level = pm860x_set_bias_level, |
1415 | 1367 | ||
1416 | .controls = pm860x_snd_controls, | 1368 | .controls = pm860x_snd_controls, |
@@ -1436,6 +1388,8 @@ static int pm860x_codec_probe(struct platform_device *pdev) | |||
1436 | pm860x->chip = chip; | 1388 | pm860x->chip = chip; |
1437 | pm860x->i2c = (chip->id == CHIP_PM8607) ? chip->client | 1389 | pm860x->i2c = (chip->id == CHIP_PM8607) ? chip->client |
1438 | : chip->companion; | 1390 | : chip->companion; |
1391 | pm860x->regmap = (chip->id == CHIP_PM8607) ? chip->regmap | ||
1392 | : chip->regmap_companion; | ||
1439 | platform_set_drvdata(pdev, pm860x); | 1393 | platform_set_drvdata(pdev, pm860x); |
1440 | 1394 | ||
1441 | for (i = 0; i < 4; i++) { | 1395 | for (i = 0; i < 4; i++) { |