1179 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// IDT821034 ALSA SoC driver4//5// Copyright 2022 CS GROUP France6//7// Author: Herve Codina <herve.codina@bootlin.com>8 9#include <linux/bitrev.h>10#include <linux/gpio/driver.h>11#include <linux/module.h>12#include <linux/slab.h>13#include <linux/spi/spi.h>14#include <sound/pcm_params.h>15#include <sound/soc.h>16#include <sound/tlv.h>17 18#define IDT821034_NB_CHANNEL 419 20struct idt821034_amp {21 u16 gain;22 bool is_muted;23};24 25struct idt821034 {26 struct spi_device *spi;27 struct mutex mutex;28 u8 spi_tx_buf; /* Cannot use stack area for SPI (dma-safe memory) */29 u8 spi_rx_buf; /* Cannot use stack area for SPI (dma-safe memory) */30 struct {31 u8 codec_conf;32 struct {33 u8 power;34 u8 tx_slot;35 u8 rx_slot;36 u8 slic_conf;37 u8 slic_control;38 } ch[IDT821034_NB_CHANNEL];39 } cache;40 struct {41 struct {42 struct idt821034_amp amp_out;43 struct idt821034_amp amp_in;44 } ch[IDT821034_NB_CHANNEL];45 } amps;46 int max_ch_playback;47 int max_ch_capture;48 struct gpio_chip gpio_chip;49};50 51static int idt821034_8bit_write(struct idt821034 *idt821034, u8 val)52{53 struct spi_transfer xfer[] = {54 {55 .tx_buf = &idt821034->spi_tx_buf,56 .len = 1,57 }, {58 .cs_off = 1,59 .tx_buf = &idt821034->spi_tx_buf,60 .len = 1,61 }62 };63 64 idt821034->spi_tx_buf = val;65 66 dev_vdbg(&idt821034->spi->dev, "spi xfer wr 0x%x\n", val);67 68 return spi_sync_transfer(idt821034->spi, xfer, 2);69}70 71static int idt821034_2x8bit_write(struct idt821034 *idt821034, u8 val1, u8 val2)72{73 int ret;74 75 ret = idt821034_8bit_write(idt821034, val1);76 if (ret)77 return ret;78 return idt821034_8bit_write(idt821034, val2);79}80 81static int idt821034_8bit_read(struct idt821034 *idt821034, u8 valw, u8 *valr)82{83 struct spi_transfer xfer[] = {84 {85 .tx_buf = &idt821034->spi_tx_buf,86 .rx_buf = &idt821034->spi_rx_buf,87 .len = 1,88 }, {89 .cs_off = 1,90 .tx_buf = &idt821034->spi_tx_buf,91 .len = 1,92 }93 };94 int ret;95 96 idt821034->spi_tx_buf = valw;97 98 ret = spi_sync_transfer(idt821034->spi, xfer, 2);99 if (ret)100 return ret;101 102 *valr = idt821034->spi_rx_buf;103 104 dev_vdbg(&idt821034->spi->dev, "spi xfer wr 0x%x, rd 0x%x\n",105 valw, *valr);106 107 return 0;108}109 110/* Available mode for the programming sequence */111#define IDT821034_MODE_CODEC(_ch) (0x80 | ((_ch) << 2))112#define IDT821034_MODE_SLIC(_ch) (0xD0 | ((_ch) << 2))113#define IDT821034_MODE_GAIN(_ch) (0xC0 | ((_ch) << 2))114 115/* Power values that can be used in 'power' (can be ORed) */116#define IDT821034_CONF_PWRUP_TX BIT(1) /* from analog input to PCM */117#define IDT821034_CONF_PWRUP_RX BIT(0) /* from PCM to analog output */118 119static int idt821034_set_channel_power(struct idt821034 *idt821034, u8 ch, u8 power)120{121 u8 conf;122 int ret;123 124 dev_dbg(&idt821034->spi->dev, "set_channel_power(%u, 0x%x)\n", ch, power);125 126 conf = IDT821034_MODE_CODEC(ch) | idt821034->cache.codec_conf;127 128 if (power & IDT821034_CONF_PWRUP_RX) {129 ret = idt821034_2x8bit_write(idt821034,130 conf | IDT821034_CONF_PWRUP_RX,131 idt821034->cache.ch[ch].rx_slot);132 if (ret)133 return ret;134 }135 if (power & IDT821034_CONF_PWRUP_TX) {136 ret = idt821034_2x8bit_write(idt821034,137 conf | IDT821034_CONF_PWRUP_TX,138 idt821034->cache.ch[ch].tx_slot);139 if (ret)140 return ret;141 }142 if (!(power & (IDT821034_CONF_PWRUP_TX | IDT821034_CONF_PWRUP_RX))) {143 ret = idt821034_2x8bit_write(idt821034, conf, 0);144 if (ret)145 return ret;146 }147 148 idt821034->cache.ch[ch].power = power;149 150 return 0;151}152 153static u8 idt821034_get_channel_power(struct idt821034 *idt821034, u8 ch)154{155 return idt821034->cache.ch[ch].power;156}157 158/* Codec configuration values that can be used in 'codec_conf' (can be ORed) */159#define IDT821034_CONF_ALAW_MODE BIT(5)160#define IDT821034_CONF_DELAY_MODE BIT(4)161 162static int idt821034_set_codec_conf(struct idt821034 *idt821034, u8 codec_conf)163{164 u8 conf;165 u8 ts;166 int ret;167 168 dev_dbg(&idt821034->spi->dev, "set_codec_conf(0x%x)\n", codec_conf);169 170 /* codec conf fields are common to all channel.171 * Arbitrary use of channel 0 for this configuration.172 */173 174 /* Set Configuration Register */175 conf = IDT821034_MODE_CODEC(0) | codec_conf;176 177 /* Update conf value and timeslot register value according178 * to cache values179 */180 if (idt821034->cache.ch[0].power & IDT821034_CONF_PWRUP_RX) {181 conf |= IDT821034_CONF_PWRUP_RX;182 ts = idt821034->cache.ch[0].rx_slot;183 } else if (idt821034->cache.ch[0].power & IDT821034_CONF_PWRUP_TX) {184 conf |= IDT821034_CONF_PWRUP_TX;185 ts = idt821034->cache.ch[0].tx_slot;186 } else {187 ts = 0x00;188 }189 190 /* Write configuration register and time-slot register */191 ret = idt821034_2x8bit_write(idt821034, conf, ts);192 if (ret)193 return ret;194 195 idt821034->cache.codec_conf = codec_conf;196 return 0;197}198 199static u8 idt821034_get_codec_conf(struct idt821034 *idt821034)200{201 return idt821034->cache.codec_conf;202}203 204/* Channel direction values that can be used in 'ch_dir' (can be ORed) */205#define IDT821034_CH_RX BIT(0) /* from PCM to analog output */206#define IDT821034_CH_TX BIT(1) /* from analog input to PCM */207 208static int idt821034_set_channel_ts(struct idt821034 *idt821034, u8 ch, u8 ch_dir, u8 ts_num)209{210 u8 conf;211 int ret;212 213 dev_dbg(&idt821034->spi->dev, "set_channel_ts(%u, 0x%x, %d)\n", ch, ch_dir, ts_num);214 215 conf = IDT821034_MODE_CODEC(ch) | idt821034->cache.codec_conf;216 217 if (ch_dir & IDT821034_CH_RX) {218 if (idt821034->cache.ch[ch].power & IDT821034_CONF_PWRUP_RX) {219 ret = idt821034_2x8bit_write(idt821034,220 conf | IDT821034_CONF_PWRUP_RX,221 ts_num);222 if (ret)223 return ret;224 }225 idt821034->cache.ch[ch].rx_slot = ts_num;226 }227 if (ch_dir & IDT821034_CH_TX) {228 if (idt821034->cache.ch[ch].power & IDT821034_CONF_PWRUP_TX) {229 ret = idt821034_2x8bit_write(idt821034,230 conf | IDT821034_CONF_PWRUP_TX,231 ts_num);232 if (ret)233 return ret;234 }235 idt821034->cache.ch[ch].tx_slot = ts_num;236 }237 238 return 0;239}240 241/* SLIC direction values that can be used in 'slic_dir' (can be ORed) */242#define IDT821034_SLIC_IO1_IN BIT(1)243#define IDT821034_SLIC_IO0_IN BIT(0)244 245static int idt821034_set_slic_conf(struct idt821034 *idt821034, u8 ch, u8 slic_dir)246{247 u8 conf;248 int ret;249 250 dev_dbg(&idt821034->spi->dev, "set_slic_conf(%u, 0x%x)\n", ch, slic_dir);251 252 conf = IDT821034_MODE_SLIC(ch) | slic_dir;253 ret = idt821034_2x8bit_write(idt821034, conf, idt821034->cache.ch[ch].slic_control);254 if (ret)255 return ret;256 257 idt821034->cache.ch[ch].slic_conf = slic_dir;258 259 return 0;260}261 262static u8 idt821034_get_slic_conf(struct idt821034 *idt821034, u8 ch)263{264 return idt821034->cache.ch[ch].slic_conf;265}266 267static int idt821034_write_slic_raw(struct idt821034 *idt821034, u8 ch, u8 slic_raw)268{269 u8 conf;270 int ret;271 272 dev_dbg(&idt821034->spi->dev, "write_slic_raw(%u, 0x%x)\n", ch, slic_raw);273 274 /*275 * On write, slic_raw is mapped as follow :276 * b4: O_4277 * b3: O_3278 * b2: O_2279 * b1: I/O_1280 * b0: I/O_0281 */282 283 conf = IDT821034_MODE_SLIC(ch) | idt821034->cache.ch[ch].slic_conf;284 ret = idt821034_2x8bit_write(idt821034, conf, slic_raw);285 if (ret)286 return ret;287 288 idt821034->cache.ch[ch].slic_control = slic_raw;289 return 0;290}291 292static u8 idt821034_get_written_slic_raw(struct idt821034 *idt821034, u8 ch)293{294 return idt821034->cache.ch[ch].slic_control;295}296 297static int idt821034_read_slic_raw(struct idt821034 *idt821034, u8 ch, u8 *slic_raw)298{299 u8 val;300 int ret;301 302 /*303 * On read, slic_raw is mapped as follow :304 * b7: I/O_0305 * b6: I/O_1306 * b5: O_2307 * b4: O_3308 * b3: O_4309 * b2: I/O1_0, I/O_0 from channel 1 (no matter ch value)310 * b1: I/O2_0, I/O_0 from channel 2 (no matter ch value)311 * b2: I/O3_0, I/O_0 from channel 3 (no matter ch value)312 */313 314 val = IDT821034_MODE_SLIC(ch) | idt821034->cache.ch[ch].slic_conf;315 ret = idt821034_8bit_write(idt821034, val);316 if (ret)317 return ret;318 319 ret = idt821034_8bit_read(idt821034, idt821034->cache.ch[ch].slic_control, slic_raw);320 if (ret)321 return ret;322 323 dev_dbg(&idt821034->spi->dev, "read_slic_raw(%i) 0x%x\n", ch, *slic_raw);324 325 return 0;326}327 328/* Gain type values that can be used in 'gain_type' (cannot be ORed) */329#define IDT821034_GAIN_RX (0 << 1) /* from PCM to analog output */330#define IDT821034_GAIN_TX (1 << 1) /* from analog input to PCM */331 332static int idt821034_set_gain_channel(struct idt821034 *idt821034, u8 ch,333 u8 gain_type, u16 gain_val)334{335 u8 conf;336 int ret;337 338 dev_dbg(&idt821034->spi->dev, "set_gain_channel(%u, 0x%x, 0x%x-%d)\n",339 ch, gain_type, gain_val, gain_val);340 341 /*342 * The gain programming coefficients should be calculated as:343 * Transmit : Coeff_X = round [ gain_X0dB × gain_X ]344 * Receive: Coeff_R = round [ gain_R0dB × gain_R ]345 * where:346 * gain_X0dB = 1820;347 * gain_X is the target gain;348 * Coeff_X should be in the range of 0 to 8192.349 * gain_R0dB = 2506;350 * gain_R is the target gain;351 * Coeff_R should be in the range of 0 to 8192.352 *353 * A gain programming coefficient is 14-bit wide and in binary format.354 * The 7 Most Significant Bits of the coefficient is called355 * GA_MSB_Transmit for transmit path, or is called GA_MSB_Receive for356 * receive path; The 7 Least Significant Bits of the coefficient is357 * called GA_LSB_ Transmit for transmit path, or is called358 * GA_LSB_Receive for receive path.359 *360 * An example is given below to clarify the calculation of the361 * coefficient. To program a +3 dB gain in transmit path and a -3.5 dB362 * gain in receive path:363 *364 * Linear Code of +3dB = 10^(3/20)= 1.412537545365 * Coeff_X = round (1820 × 1.412537545) = 2571366 * = 0b001010_00001011367 * GA_MSB_Transmit = 0b0010100368 * GA_LSB_Transmit = 0b0001011369 *370 * Linear Code of -3.5dB = 10^(-3.5/20) = 0.668343917371 * Coeff_R= round (2506 × 0.668343917) = 1675372 * = 0b0001101_0001011373 * GA_MSB_Receive = 0b0001101374 * GA_LSB_Receive = 0b0001011375 */376 377 conf = IDT821034_MODE_GAIN(ch) | gain_type;378 379 ret = idt821034_2x8bit_write(idt821034, conf | 0x00, gain_val & 0x007F);380 if (ret)381 return ret;382 383 ret = idt821034_2x8bit_write(idt821034, conf | 0x01, (gain_val >> 7) & 0x7F);384 if (ret)385 return ret;386 387 return 0;388}389 390/* Id helpers used in controls and dapm */391#define IDT821034_DIR_OUT (1 << 3)392#define IDT821034_DIR_IN (0 << 3)393#define IDT821034_ID(_ch, _dir) (((_ch) & 0x03) | (_dir))394#define IDT821034_ID_OUT(_ch) IDT821034_ID(_ch, IDT821034_DIR_OUT)395#define IDT821034_ID_IN(_ch) IDT821034_ID(_ch, IDT821034_DIR_IN)396 397#define IDT821034_ID_GET_CHAN(_id) ((_id) & 0x03)398#define IDT821034_ID_GET_DIR(_id) ((_id) & (1 << 3))399#define IDT821034_ID_IS_OUT(_id) (IDT821034_ID_GET_DIR(_id) == IDT821034_DIR_OUT)400 401static int idt821034_kctrl_gain_get(struct snd_kcontrol *kcontrol,402 struct snd_ctl_elem_value *ucontrol)403{404 struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;405 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);406 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(component);407 int min = mc->min;408 int max = mc->max;409 unsigned int mask = (1 << fls(max)) - 1;410 unsigned int invert = mc->invert;411 int val;412 u8 ch;413 414 ch = IDT821034_ID_GET_CHAN(mc->reg);415 416 mutex_lock(&idt821034->mutex);417 if (IDT821034_ID_IS_OUT(mc->reg))418 val = idt821034->amps.ch[ch].amp_out.gain;419 else420 val = idt821034->amps.ch[ch].amp_in.gain;421 mutex_unlock(&idt821034->mutex);422 423 ucontrol->value.integer.value[0] = val & mask;424 if (invert)425 ucontrol->value.integer.value[0] = max - ucontrol->value.integer.value[0];426 else427 ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] - min;428 429 return 0;430}431 432static int idt821034_kctrl_gain_put(struct snd_kcontrol *kcontrol,433 struct snd_ctl_elem_value *ucontrol)434{435 struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;436 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);437 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(component);438 struct idt821034_amp *amp;439 int min = mc->min;440 int max = mc->max;441 unsigned int mask = (1 << fls(max)) - 1;442 unsigned int invert = mc->invert;443 unsigned int val;444 int ret;445 u8 gain_type;446 u8 ch;447 448 val = ucontrol->value.integer.value[0];449 if (val > max - min)450 return -EINVAL;451 452 if (invert)453 val = (max - val) & mask;454 else455 val = (val + min) & mask;456 457 ch = IDT821034_ID_GET_CHAN(mc->reg);458 459 mutex_lock(&idt821034->mutex);460 461 if (IDT821034_ID_IS_OUT(mc->reg)) {462 amp = &idt821034->amps.ch[ch].amp_out;463 gain_type = IDT821034_GAIN_RX;464 } else {465 amp = &idt821034->amps.ch[ch].amp_in;466 gain_type = IDT821034_GAIN_TX;467 }468 469 if (amp->gain == val) {470 ret = 0;471 goto end;472 }473 474 if (!amp->is_muted) {475 ret = idt821034_set_gain_channel(idt821034, ch, gain_type, val);476 if (ret)477 goto end;478 }479 480 amp->gain = val;481 ret = 1; /* The value changed */482end:483 mutex_unlock(&idt821034->mutex);484 return ret;485}486 487static int idt821034_kctrl_mute_get(struct snd_kcontrol *kcontrol,488 struct snd_ctl_elem_value *ucontrol)489{490 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);491 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(component);492 int id = kcontrol->private_value;493 bool is_muted;494 u8 ch;495 496 ch = IDT821034_ID_GET_CHAN(id);497 498 mutex_lock(&idt821034->mutex);499 is_muted = IDT821034_ID_IS_OUT(id) ?500 idt821034->amps.ch[ch].amp_out.is_muted :501 idt821034->amps.ch[ch].amp_in.is_muted;502 mutex_unlock(&idt821034->mutex);503 504 ucontrol->value.integer.value[0] = !is_muted;505 506 return 0;507}508 509static int idt821034_kctrl_mute_put(struct snd_kcontrol *kcontrol,510 struct snd_ctl_elem_value *ucontrol)511{512 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);513 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(component);514 int id = kcontrol->private_value;515 struct idt821034_amp *amp;516 bool is_mute;517 u8 gain_type;518 int ret;519 u8 ch;520 521 ch = IDT821034_ID_GET_CHAN(id);522 is_mute = !ucontrol->value.integer.value[0];523 524 mutex_lock(&idt821034->mutex);525 526 if (IDT821034_ID_IS_OUT(id)) {527 amp = &idt821034->amps.ch[ch].amp_out;528 gain_type = IDT821034_GAIN_RX;529 } else {530 amp = &idt821034->amps.ch[ch].amp_in;531 gain_type = IDT821034_GAIN_TX;532 }533 534 if (amp->is_muted == is_mute) {535 ret = 0;536 goto end;537 }538 539 ret = idt821034_set_gain_channel(idt821034, ch, gain_type,540 is_mute ? 0 : amp->gain);541 if (ret)542 goto end;543 544 amp->is_muted = is_mute;545 ret = 1; /* The value changed */546end:547 mutex_unlock(&idt821034->mutex);548 return ret;549}550 551static const DECLARE_TLV_DB_LINEAR(idt821034_gain_in, -6520, 1306);552#define IDT821034_GAIN_IN_MIN_RAW 1 /* -65.20 dB -> 10^(-65.2/20.0) * 1820 = 1 */553#define IDT821034_GAIN_IN_MAX_RAW 8191 /* 13.06 dB -> 10^(13.06/20.0) * 1820 = 8191 */554#define IDT821034_GAIN_IN_INIT_RAW 1820 /* 0dB -> 10^(0/20) * 1820 = 1820 */555 556static const DECLARE_TLV_DB_LINEAR(idt821034_gain_out, -6798, 1029);557#define IDT821034_GAIN_OUT_MIN_RAW 1 /* -67.98 dB -> 10^(-67.98/20.0) * 2506 = 1*/558#define IDT821034_GAIN_OUT_MAX_RAW 8191 /* 10.29 dB -> 10^(10.29/20.0) * 2506 = 8191 */559#define IDT821034_GAIN_OUT_INIT_RAW 2506 /* 0dB -> 10^(0/20) * 2506 = 2506 */560 561static const struct snd_kcontrol_new idt821034_controls[] = {562 /* DAC volume control */563 SOC_SINGLE_RANGE_EXT_TLV("DAC0 Playback Volume", IDT821034_ID_OUT(0), 0,564 IDT821034_GAIN_OUT_MIN_RAW, IDT821034_GAIN_OUT_MAX_RAW,565 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,566 idt821034_gain_out),567 SOC_SINGLE_RANGE_EXT_TLV("DAC1 Playback Volume", IDT821034_ID_OUT(1), 0,568 IDT821034_GAIN_OUT_MIN_RAW, IDT821034_GAIN_OUT_MAX_RAW,569 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,570 idt821034_gain_out),571 SOC_SINGLE_RANGE_EXT_TLV("DAC2 Playback Volume", IDT821034_ID_OUT(2), 0,572 IDT821034_GAIN_OUT_MIN_RAW, IDT821034_GAIN_OUT_MAX_RAW,573 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,574 idt821034_gain_out),575 SOC_SINGLE_RANGE_EXT_TLV("DAC3 Playback Volume", IDT821034_ID_OUT(3), 0,576 IDT821034_GAIN_OUT_MIN_RAW, IDT821034_GAIN_OUT_MAX_RAW,577 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,578 idt821034_gain_out),579 580 /* DAC mute control */581 SOC_SINGLE_BOOL_EXT("DAC0 Playback Switch", IDT821034_ID_OUT(0),582 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),583 SOC_SINGLE_BOOL_EXT("DAC1 Playback Switch", IDT821034_ID_OUT(1),584 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),585 SOC_SINGLE_BOOL_EXT("DAC2 Playback Switch", IDT821034_ID_OUT(2),586 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),587 SOC_SINGLE_BOOL_EXT("DAC3 Playback Switch", IDT821034_ID_OUT(3),588 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),589 590 /* ADC volume control */591 SOC_SINGLE_RANGE_EXT_TLV("ADC0 Capture Volume", IDT821034_ID_IN(0), 0,592 IDT821034_GAIN_IN_MIN_RAW, IDT821034_GAIN_IN_MAX_RAW,593 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,594 idt821034_gain_in),595 SOC_SINGLE_RANGE_EXT_TLV("ADC1 Capture Volume", IDT821034_ID_IN(1), 0,596 IDT821034_GAIN_IN_MIN_RAW, IDT821034_GAIN_IN_MAX_RAW,597 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,598 idt821034_gain_in),599 SOC_SINGLE_RANGE_EXT_TLV("ADC2 Capture Volume", IDT821034_ID_IN(2), 0,600 IDT821034_GAIN_IN_MIN_RAW, IDT821034_GAIN_IN_MAX_RAW,601 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,602 idt821034_gain_in),603 SOC_SINGLE_RANGE_EXT_TLV("ADC3 Capture Volume", IDT821034_ID_IN(3), 0,604 IDT821034_GAIN_IN_MIN_RAW, IDT821034_GAIN_IN_MAX_RAW,605 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,606 idt821034_gain_in),607 608 /* ADC mute control */609 SOC_SINGLE_BOOL_EXT("ADC0 Capture Switch", IDT821034_ID_IN(0),610 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),611 SOC_SINGLE_BOOL_EXT("ADC1 Capture Switch", IDT821034_ID_IN(1),612 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),613 SOC_SINGLE_BOOL_EXT("ADC2 Capture Switch", IDT821034_ID_IN(2),614 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),615 SOC_SINGLE_BOOL_EXT("ADC3 Capture Switch", IDT821034_ID_IN(3),616 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),617};618 619static int idt821034_power_event(struct snd_soc_dapm_widget *w,620 struct snd_kcontrol *kcontrol, int event)621{622 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);623 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(component);624 unsigned int id = w->shift;625 u8 power, mask;626 int ret;627 u8 ch;628 629 ch = IDT821034_ID_GET_CHAN(id);630 mask = IDT821034_ID_IS_OUT(id) ? IDT821034_CONF_PWRUP_RX : IDT821034_CONF_PWRUP_TX;631 632 mutex_lock(&idt821034->mutex);633 634 power = idt821034_get_channel_power(idt821034, ch);635 if (SND_SOC_DAPM_EVENT_ON(event))636 power |= mask;637 else638 power &= ~mask;639 ret = idt821034_set_channel_power(idt821034, ch, power);640 641 mutex_unlock(&idt821034->mutex);642 643 return ret;644}645 646static const struct snd_soc_dapm_widget idt821034_dapm_widgets[] = {647 SND_SOC_DAPM_DAC_E("DAC0", "Playback", SND_SOC_NOPM, IDT821034_ID_OUT(0), 0,648 idt821034_power_event,649 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),650 SND_SOC_DAPM_DAC_E("DAC1", "Playback", SND_SOC_NOPM, IDT821034_ID_OUT(1), 0,651 idt821034_power_event,652 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),653 SND_SOC_DAPM_DAC_E("DAC2", "Playback", SND_SOC_NOPM, IDT821034_ID_OUT(2), 0,654 idt821034_power_event,655 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),656 SND_SOC_DAPM_DAC_E("DAC3", "Playback", SND_SOC_NOPM, IDT821034_ID_OUT(3), 0,657 idt821034_power_event,658 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),659 660 SND_SOC_DAPM_OUTPUT("OUT0"),661 SND_SOC_DAPM_OUTPUT("OUT1"),662 SND_SOC_DAPM_OUTPUT("OUT2"),663 SND_SOC_DAPM_OUTPUT("OUT3"),664 665 SND_SOC_DAPM_DAC_E("ADC0", "Capture", SND_SOC_NOPM, IDT821034_ID_IN(0), 0,666 idt821034_power_event,667 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),668 SND_SOC_DAPM_DAC_E("ADC1", "Capture", SND_SOC_NOPM, IDT821034_ID_IN(1), 0,669 idt821034_power_event,670 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),671 SND_SOC_DAPM_DAC_E("ADC2", "Capture", SND_SOC_NOPM, IDT821034_ID_IN(2), 0,672 idt821034_power_event,673 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),674 SND_SOC_DAPM_DAC_E("ADC3", "Capture", SND_SOC_NOPM, IDT821034_ID_IN(3), 0,675 idt821034_power_event,676 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),677 678 SND_SOC_DAPM_INPUT("IN0"),679 SND_SOC_DAPM_INPUT("IN1"),680 SND_SOC_DAPM_INPUT("IN2"),681 SND_SOC_DAPM_INPUT("IN3"),682};683 684static const struct snd_soc_dapm_route idt821034_dapm_routes[] = {685 { "OUT0", NULL, "DAC0" },686 { "OUT1", NULL, "DAC1" },687 { "OUT2", NULL, "DAC2" },688 { "OUT3", NULL, "DAC3" },689 690 { "ADC0", NULL, "IN0" },691 { "ADC1", NULL, "IN1" },692 { "ADC2", NULL, "IN2" },693 { "ADC3", NULL, "IN3" },694};695 696static int idt821034_dai_set_tdm_slot(struct snd_soc_dai *dai,697 unsigned int tx_mask, unsigned int rx_mask,698 int slots, int width)699{700 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(dai->component);701 unsigned int mask;702 u8 slot;703 int ret;704 u8 ch;705 706 switch (width) {707 case 0: /* Not set -> default 8 */708 case 8:709 break;710 default:711 dev_err(dai->dev, "tdm slot width %d not supported\n", width);712 return -EINVAL;713 }714 715 mask = tx_mask;716 slot = 0;717 ch = 0;718 while (mask && ch < IDT821034_NB_CHANNEL) {719 if (mask & 0x1) {720 mutex_lock(&idt821034->mutex);721 ret = idt821034_set_channel_ts(idt821034, ch, IDT821034_CH_RX, slot);722 mutex_unlock(&idt821034->mutex);723 if (ret) {724 dev_err(dai->dev, "ch%u set tx tdm slot failed (%d)\n",725 ch, ret);726 return ret;727 }728 ch++;729 }730 mask >>= 1;731 slot++;732 }733 if (mask) {734 dev_err(dai->dev, "too much tx slots defined (mask = 0x%x) support max %d\n",735 tx_mask, IDT821034_NB_CHANNEL);736 return -EINVAL;737 }738 idt821034->max_ch_playback = ch;739 740 mask = rx_mask;741 slot = 0;742 ch = 0;743 while (mask && ch < IDT821034_NB_CHANNEL) {744 if (mask & 0x1) {745 mutex_lock(&idt821034->mutex);746 ret = idt821034_set_channel_ts(idt821034, ch, IDT821034_CH_TX, slot);747 mutex_unlock(&idt821034->mutex);748 if (ret) {749 dev_err(dai->dev, "ch%u set rx tdm slot failed (%d)\n",750 ch, ret);751 return ret;752 }753 ch++;754 }755 mask >>= 1;756 slot++;757 }758 if (mask) {759 dev_err(dai->dev, "too much rx slots defined (mask = 0x%x) support max %d\n",760 rx_mask, IDT821034_NB_CHANNEL);761 return -EINVAL;762 }763 idt821034->max_ch_capture = ch;764 765 return 0;766}767 768static int idt821034_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)769{770 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(dai->component);771 u8 conf;772 int ret;773 774 mutex_lock(&idt821034->mutex);775 776 conf = idt821034_get_codec_conf(idt821034);777 778 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {779 case SND_SOC_DAIFMT_DSP_A:780 conf |= IDT821034_CONF_DELAY_MODE;781 break;782 case SND_SOC_DAIFMT_DSP_B:783 conf &= ~IDT821034_CONF_DELAY_MODE;784 break;785 default:786 dev_err(dai->dev, "Unsupported DAI format 0x%x\n",787 fmt & SND_SOC_DAIFMT_FORMAT_MASK);788 ret = -EINVAL;789 goto end;790 }791 ret = idt821034_set_codec_conf(idt821034, conf);792end:793 mutex_unlock(&idt821034->mutex);794 return ret;795}796 797static int idt821034_dai_hw_params(struct snd_pcm_substream *substream,798 struct snd_pcm_hw_params *params,799 struct snd_soc_dai *dai)800{801 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(dai->component);802 u8 conf;803 int ret;804 805 mutex_lock(&idt821034->mutex);806 807 conf = idt821034_get_codec_conf(idt821034);808 809 switch (params_format(params)) {810 case SNDRV_PCM_FORMAT_A_LAW:811 conf |= IDT821034_CONF_ALAW_MODE;812 break;813 case SNDRV_PCM_FORMAT_MU_LAW:814 conf &= ~IDT821034_CONF_ALAW_MODE;815 break;816 default:817 dev_err(dai->dev, "Unsupported PCM format 0x%x\n",818 params_format(params));819 ret = -EINVAL;820 goto end;821 }822 ret = idt821034_set_codec_conf(idt821034, conf);823end:824 mutex_unlock(&idt821034->mutex);825 return ret;826}827 828static const unsigned int idt821034_sample_bits[] = {8};829 830static struct snd_pcm_hw_constraint_list idt821034_sample_bits_constr = {831 .list = idt821034_sample_bits,832 .count = ARRAY_SIZE(idt821034_sample_bits),833};834 835static int idt821034_dai_startup(struct snd_pcm_substream *substream,836 struct snd_soc_dai *dai)837{838 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(dai->component);839 unsigned int max_ch = 0;840 int ret;841 842 max_ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?843 idt821034->max_ch_playback : idt821034->max_ch_capture;844 845 /*846 * Disable stream support (min = 0, max = 0) if no timeslots were847 * configured otherwise, limit the number of channels to those848 * configured.849 */850 ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_CHANNELS,851 max_ch ? 1 : 0, max_ch);852 if (ret < 0)853 return ret;854 855 ret = snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,856 &idt821034_sample_bits_constr);857 if (ret)858 return ret;859 860 return 0;861}862 863static const u64 idt821034_dai_formats[] = {864 SND_SOC_POSSIBLE_DAIFMT_DSP_A |865 SND_SOC_POSSIBLE_DAIFMT_DSP_B,866};867 868static const struct snd_soc_dai_ops idt821034_dai_ops = {869 .startup = idt821034_dai_startup,870 .hw_params = idt821034_dai_hw_params,871 .set_tdm_slot = idt821034_dai_set_tdm_slot,872 .set_fmt = idt821034_dai_set_fmt,873 .auto_selectable_formats = idt821034_dai_formats,874 .num_auto_selectable_formats = ARRAY_SIZE(idt821034_dai_formats),875};876 877static struct snd_soc_dai_driver idt821034_dai_driver = {878 .name = "idt821034",879 .playback = {880 .stream_name = "Playback",881 .channels_min = 1,882 .channels_max = IDT821034_NB_CHANNEL,883 .rates = SNDRV_PCM_RATE_8000,884 .formats = SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,885 },886 .capture = {887 .stream_name = "Capture",888 .channels_min = 1,889 .channels_max = IDT821034_NB_CHANNEL,890 .rates = SNDRV_PCM_RATE_8000,891 .formats = SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,892 },893 .ops = &idt821034_dai_ops,894};895 896static int idt821034_reset_audio(struct idt821034 *idt821034)897{898 int ret;899 u8 i;900 901 mutex_lock(&idt821034->mutex);902 903 ret = idt821034_set_codec_conf(idt821034, 0);904 if (ret)905 goto end;906 907 for (i = 0; i < IDT821034_NB_CHANNEL; i++) {908 idt821034->amps.ch[i].amp_out.gain = IDT821034_GAIN_OUT_INIT_RAW;909 idt821034->amps.ch[i].amp_out.is_muted = false;910 ret = idt821034_set_gain_channel(idt821034, i, IDT821034_GAIN_RX,911 idt821034->amps.ch[i].amp_out.gain);912 if (ret)913 goto end;914 915 idt821034->amps.ch[i].amp_in.gain = IDT821034_GAIN_IN_INIT_RAW;916 idt821034->amps.ch[i].amp_in.is_muted = false;917 ret = idt821034_set_gain_channel(idt821034, i, IDT821034_GAIN_TX,918 idt821034->amps.ch[i].amp_in.gain);919 if (ret)920 goto end;921 922 ret = idt821034_set_channel_power(idt821034, i, 0);923 if (ret)924 goto end;925 }926 927 ret = 0;928end:929 mutex_unlock(&idt821034->mutex);930 return ret;931}932 933static int idt821034_component_probe(struct snd_soc_component *component)934{935 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(component);936 int ret;937 938 /* reset idt821034 audio part*/939 ret = idt821034_reset_audio(idt821034);940 if (ret)941 return ret;942 943 return 0;944}945 946static const struct snd_soc_component_driver idt821034_component_driver = {947 .probe = idt821034_component_probe,948 .controls = idt821034_controls,949 .num_controls = ARRAY_SIZE(idt821034_controls),950 .dapm_widgets = idt821034_dapm_widgets,951 .num_dapm_widgets = ARRAY_SIZE(idt821034_dapm_widgets),952 .dapm_routes = idt821034_dapm_routes,953 .num_dapm_routes = ARRAY_SIZE(idt821034_dapm_routes),954 .endianness = 1,955};956 957#define IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(_offset) (((_offset) / 5) % 4)958#define IDT821034_GPIO_OFFSET_TO_SLIC_MASK(_offset) BIT((_offset) % 5)959 960static void idt821034_chip_gpio_set(struct gpio_chip *c, unsigned int offset, int val)961{962 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);963 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);964 struct idt821034 *idt821034 = gpiochip_get_data(c);965 u8 slic_raw;966 int ret;967 968 mutex_lock(&idt821034->mutex);969 970 slic_raw = idt821034_get_written_slic_raw(idt821034, ch);971 if (val)972 slic_raw |= mask;973 else974 slic_raw &= ~mask;975 ret = idt821034_write_slic_raw(idt821034, ch, slic_raw);976 if (ret) {977 dev_err(&idt821034->spi->dev, "set gpio %d (%u, 0x%x) failed (%d)\n",978 offset, ch, mask, ret);979 }980 981 mutex_unlock(&idt821034->mutex);982}983 984static int idt821034_chip_gpio_get(struct gpio_chip *c, unsigned int offset)985{986 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);987 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);988 struct idt821034 *idt821034 = gpiochip_get_data(c);989 u8 slic_raw;990 int ret;991 992 mutex_lock(&idt821034->mutex);993 ret = idt821034_read_slic_raw(idt821034, ch, &slic_raw);994 mutex_unlock(&idt821034->mutex);995 if (ret) {996 dev_err(&idt821034->spi->dev, "get gpio %d (%u, 0x%x) failed (%d)\n",997 offset, ch, mask, ret);998 return ret;999 }1000 1001 /*1002 * SLIC IOs are read in reverse order compared to write.1003 * Reverse the read value here in order to have IO0 at lsb (ie same1004 * order as write)1005 */1006 return !!(bitrev8(slic_raw) & mask);1007}1008 1009static int idt821034_chip_get_direction(struct gpio_chip *c, unsigned int offset)1010{1011 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);1012 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);1013 struct idt821034 *idt821034 = gpiochip_get_data(c);1014 u8 slic_dir;1015 1016 mutex_lock(&idt821034->mutex);1017 slic_dir = idt821034_get_slic_conf(idt821034, ch);1018 mutex_unlock(&idt821034->mutex);1019 1020 return slic_dir & mask ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;1021}1022 1023static int idt821034_chip_direction_input(struct gpio_chip *c, unsigned int offset)1024{1025 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);1026 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);1027 struct idt821034 *idt821034 = gpiochip_get_data(c);1028 u8 slic_conf;1029 int ret;1030 1031 /* Only IO0 and IO1 can be set as input */1032 if (mask & ~(IDT821034_SLIC_IO1_IN | IDT821034_SLIC_IO0_IN))1033 return -EPERM;1034 1035 mutex_lock(&idt821034->mutex);1036 1037 slic_conf = idt821034_get_slic_conf(idt821034, ch) | mask;1038 1039 ret = idt821034_set_slic_conf(idt821034, ch, slic_conf);1040 if (ret) {1041 dev_err(&idt821034->spi->dev, "dir in gpio %d (%u, 0x%x) failed (%d)\n",1042 offset, ch, mask, ret);1043 }1044 1045 mutex_unlock(&idt821034->mutex);1046 return ret;1047}1048 1049static int idt821034_chip_direction_output(struct gpio_chip *c, unsigned int offset, int val)1050{1051 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);1052 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);1053 struct idt821034 *idt821034 = gpiochip_get_data(c);1054 u8 slic_conf;1055 int ret;1056 1057 idt821034_chip_gpio_set(c, offset, val);1058 1059 mutex_lock(&idt821034->mutex);1060 1061 slic_conf = idt821034_get_slic_conf(idt821034, ch) & ~mask;1062 1063 ret = idt821034_set_slic_conf(idt821034, ch, slic_conf);1064 if (ret) {1065 dev_err(&idt821034->spi->dev, "dir in gpio %d (%u, 0x%x) failed (%d)\n",1066 offset, ch, mask, ret);1067 }1068 1069 mutex_unlock(&idt821034->mutex);1070 return ret;1071}1072 1073static int idt821034_reset_gpio(struct idt821034 *idt821034)1074{1075 int ret;1076 u8 i;1077 1078 mutex_lock(&idt821034->mutex);1079 1080 /* IO0 and IO1 as input for all channels and output IO set to 0 */1081 for (i = 0; i < IDT821034_NB_CHANNEL; i++) {1082 ret = idt821034_set_slic_conf(idt821034, i,1083 IDT821034_SLIC_IO1_IN | IDT821034_SLIC_IO0_IN);1084 if (ret)1085 goto end;1086 1087 ret = idt821034_write_slic_raw(idt821034, i, 0);1088 if (ret)1089 goto end;1090 1091 }1092 ret = 0;1093end:1094 mutex_unlock(&idt821034->mutex);1095 return ret;1096}1097 1098static int idt821034_gpio_init(struct idt821034 *idt821034)1099{1100 int ret;1101 1102 ret = idt821034_reset_gpio(idt821034);1103 if (ret)1104 return ret;1105 1106 idt821034->gpio_chip.owner = THIS_MODULE;1107 idt821034->gpio_chip.label = dev_name(&idt821034->spi->dev);1108 idt821034->gpio_chip.parent = &idt821034->spi->dev;1109 idt821034->gpio_chip.base = -1;1110 idt821034->gpio_chip.ngpio = 5 * 4; /* 5 GPIOs on 4 channels */1111 idt821034->gpio_chip.get_direction = idt821034_chip_get_direction;1112 idt821034->gpio_chip.direction_input = idt821034_chip_direction_input;1113 idt821034->gpio_chip.direction_output = idt821034_chip_direction_output;1114 idt821034->gpio_chip.get = idt821034_chip_gpio_get;1115 idt821034->gpio_chip.set = idt821034_chip_gpio_set;1116 idt821034->gpio_chip.can_sleep = true;1117 1118 return devm_gpiochip_add_data(&idt821034->spi->dev, &idt821034->gpio_chip,1119 idt821034);1120}1121 1122static int idt821034_spi_probe(struct spi_device *spi)1123{1124 struct idt821034 *idt821034;1125 int ret;1126 1127 spi->bits_per_word = 8;1128 ret = spi_setup(spi);1129 if (ret < 0)1130 return ret;1131 1132 idt821034 = devm_kzalloc(&spi->dev, sizeof(*idt821034), GFP_KERNEL);1133 if (!idt821034)1134 return -ENOMEM;1135 1136 idt821034->spi = spi;1137 1138 mutex_init(&idt821034->mutex);1139 1140 spi_set_drvdata(spi, idt821034);1141 1142 ret = devm_snd_soc_register_component(&spi->dev, &idt821034_component_driver,1143 &idt821034_dai_driver, 1);1144 if (ret)1145 return ret;1146 1147 if (IS_ENABLED(CONFIG_GPIOLIB))1148 return idt821034_gpio_init(idt821034);1149 1150 return 0;1151}1152 1153static const struct of_device_id idt821034_of_match[] = {1154 { .compatible = "renesas,idt821034", },1155 { }1156};1157MODULE_DEVICE_TABLE(of, idt821034_of_match);1158 1159static const struct spi_device_id idt821034_id_table[] = {1160 { "idt821034", 0 },1161 { }1162};1163MODULE_DEVICE_TABLE(spi, idt821034_id_table);1164 1165static struct spi_driver idt821034_spi_driver = {1166 .driver = {1167 .name = "idt821034",1168 .of_match_table = idt821034_of_match,1169 },1170 .id_table = idt821034_id_table,1171 .probe = idt821034_spi_probe,1172};1173 1174module_spi_driver(idt821034_spi_driver);1175 1176MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");1177MODULE_DESCRIPTION("IDT821034 ALSA SoC driver");1178MODULE_LICENSE("GPL");1179