diff options
Diffstat (limited to 'sound/soc/codecs/tlv320dac33.c')
-rw-r--r-- | sound/soc/codecs/tlv320dac33.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index d251ff54a2d3..c5ab8c805771 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -58,7 +58,7 @@ | |||
58 | (1000000000 / ((rate * 1000) / samples)) | 58 | (1000000000 / ((rate * 1000) / samples)) |
59 | 59 | ||
60 | #define US_TO_SAMPLES(rate, us) \ | 60 | #define US_TO_SAMPLES(rate, us) \ |
61 | (rate / (1000000 / us)) | 61 | (rate / (1000000 / (us < 1000000 ? us : 1000000))) |
62 | 62 | ||
63 | #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ | 63 | #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ |
64 | ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) | 64 | ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) |
@@ -200,7 +200,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, | |||
200 | u8 *value) | 200 | u8 *value) |
201 | { | 201 | { |
202 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | 202 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
203 | int val; | 203 | int val, ret = 0; |
204 | 204 | ||
205 | *value = reg & 0xff; | 205 | *value = reg & 0xff; |
206 | 206 | ||
@@ -210,6 +210,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, | |||
210 | if (val < 0) { | 210 | if (val < 0) { |
211 | dev_err(codec->dev, "Read failed (%d)\n", val); | 211 | dev_err(codec->dev, "Read failed (%d)\n", val); |
212 | value[0] = dac33_read_reg_cache(codec, reg); | 212 | value[0] = dac33_read_reg_cache(codec, reg); |
213 | ret = val; | ||
213 | } else { | 214 | } else { |
214 | value[0] = val; | 215 | value[0] = val; |
215 | dac33_write_reg_cache(codec, reg, val); | 216 | dac33_write_reg_cache(codec, reg, val); |
@@ -218,7 +219,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, | |||
218 | value[0] = dac33_read_reg_cache(codec, reg); | 219 | value[0] = dac33_read_reg_cache(codec, reg); |
219 | } | 220 | } |
220 | 221 | ||
221 | return 0; | 222 | return ret; |
222 | } | 223 | } |
223 | 224 | ||
224 | static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, | 225 | static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, |
@@ -329,13 +330,18 @@ static void dac33_init_chip(struct snd_soc_codec *codec) | |||
329 | dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); | 330 | dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); |
330 | } | 331 | } |
331 | 332 | ||
332 | static inline void dac33_read_id(struct snd_soc_codec *codec) | 333 | static inline int dac33_read_id(struct snd_soc_codec *codec) |
333 | { | 334 | { |
335 | int i, ret = 0; | ||
334 | u8 reg; | 336 | u8 reg; |
335 | 337 | ||
336 | dac33_read(codec, DAC33_DEVICE_ID_MSB, ®); | 338 | for (i = 0; i < 3; i++) { |
337 | dac33_read(codec, DAC33_DEVICE_ID_LSB, ®); | 339 | ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, ®); |
338 | dac33_read(codec, DAC33_DEVICE_REV_ID, ®); | 340 | if (ret < 0) |
341 | break; | ||
342 | } | ||
343 | |||
344 | return ret; | ||
339 | } | 345 | } |
340 | 346 | ||
341 | static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) | 347 | static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) |
@@ -1076,6 +1082,9 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||
1076 | /* Number of samples under i2c latency */ | 1082 | /* Number of samples under i2c latency */ |
1077 | dac33->alarm_threshold = US_TO_SAMPLES(rate, | 1083 | dac33->alarm_threshold = US_TO_SAMPLES(rate, |
1078 | dac33->mode1_latency); | 1084 | dac33->mode1_latency); |
1085 | nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - | ||
1086 | dac33->alarm_threshold; | ||
1087 | |||
1079 | if (dac33->auto_fifo_config) { | 1088 | if (dac33->auto_fifo_config) { |
1080 | if (period_size <= dac33->alarm_threshold) | 1089 | if (period_size <= dac33->alarm_threshold) |
1081 | /* | 1090 | /* |
@@ -1086,6 +1095,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||
1086 | ((dac33->alarm_threshold / period_size) + | 1095 | ((dac33->alarm_threshold / period_size) + |
1087 | (dac33->alarm_threshold % period_size ? | 1096 | (dac33->alarm_threshold % period_size ? |
1088 | 1 : 0)); | 1097 | 1 : 0)); |
1098 | else if (period_size > nsample_limit) | ||
1099 | dac33->nsample = nsample_limit; | ||
1089 | else | 1100 | else |
1090 | dac33->nsample = period_size; | 1101 | dac33->nsample = period_size; |
1091 | } else { | 1102 | } else { |
@@ -1097,8 +1108,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||
1097 | */ | 1108 | */ |
1098 | dac33->nsample_max = substream->runtime->buffer_size - | 1109 | dac33->nsample_max = substream->runtime->buffer_size - |
1099 | period_size; | 1110 | period_size; |
1100 | nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - | 1111 | |
1101 | dac33->alarm_threshold; | ||
1102 | if (dac33->nsample_max > nsample_limit) | 1112 | if (dac33->nsample_max > nsample_limit) |
1103 | dac33->nsample_max = nsample_limit; | 1113 | dac33->nsample_max = nsample_limit; |
1104 | 1114 | ||
@@ -1414,9 +1424,15 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
1414 | dev_err(codec->dev, "Failed to power up codec: %d\n", ret); | 1424 | dev_err(codec->dev, "Failed to power up codec: %d\n", ret); |
1415 | goto err_power; | 1425 | goto err_power; |
1416 | } | 1426 | } |
1417 | dac33_read_id(codec); | 1427 | ret = dac33_read_id(codec); |
1418 | dac33_hard_power(codec, 0); | 1428 | dac33_hard_power(codec, 0); |
1419 | 1429 | ||
1430 | if (ret < 0) { | ||
1431 | dev_err(codec->dev, "Failed to read chip ID: %d\n", ret); | ||
1432 | ret = -ENODEV; | ||
1433 | goto err_power; | ||
1434 | } | ||
1435 | |||
1420 | /* Check if the IRQ number is valid and request it */ | 1436 | /* Check if the IRQ number is valid and request it */ |
1421 | if (dac33->irq >= 0) { | 1437 | if (dac33->irq >= 0) { |
1422 | ret = request_irq(dac33->irq, dac33_interrupt_handler, | 1438 | ret = request_irq(dac33->irq, dac33_interrupt_handler, |