623 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Routines for control of the CS8427 via i2c bus4 * IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>6 */7 8#include <linux/slab.h>9#include <linux/delay.h>10#include <linux/init.h>11#include <linux/bitrev.h>12#include <linux/module.h>13#include <linux/unaligned.h>14#include <sound/core.h>15#include <sound/control.h>16#include <sound/pcm.h>17#include <sound/cs8427.h>18#include <sound/asoundef.h>19 20static void snd_cs8427_reset(struct snd_i2c_device *cs8427);21 22MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");23MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");24MODULE_LICENSE("GPL");25 26#define CS8427_ADDR (0x20>>1) /* fixed address */27 28struct cs8427_stream {29 struct snd_pcm_substream *substream;30 char hw_status[24]; /* hardware status */31 char def_status[24]; /* default status */32 char pcm_status[24]; /* PCM private status */33 char hw_udata[32];34 struct snd_kcontrol *pcm_ctl;35};36 37struct cs8427 {38 unsigned char regmap[0x14]; /* map of first 1 + 13 registers */39 unsigned int rate;40 unsigned int reset_timeout;41 struct cs8427_stream playback;42 struct cs8427_stream capture;43};44 45int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,46 unsigned char val)47{48 int err;49 unsigned char buf[2];50 51 buf[0] = reg & 0x7f;52 buf[1] = val;53 err = snd_i2c_sendbytes(device, buf, 2);54 if (err != 2) {55 dev_err(device->bus->card->dev,56 "unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n",57 buf[0], buf[1], err);58 return err < 0 ? err : -EIO;59 }60 return 0;61}62 63EXPORT_SYMBOL(snd_cs8427_reg_write);64 65static int snd_cs8427_reg_read(struct snd_i2c_device *device, unsigned char reg)66{67 int err;68 unsigned char buf;69 70 err = snd_i2c_sendbytes(device, ®, 1);71 if (err != 1) {72 dev_err(device->bus->card->dev,73 "unable to send register 0x%x byte to CS8427\n", reg);74 return err < 0 ? err : -EIO;75 }76 err = snd_i2c_readbytes(device, &buf, 1);77 if (err != 1) {78 dev_err(device->bus->card->dev,79 "unable to read register 0x%x byte from CS8427\n", reg);80 return err < 0 ? err : -EIO;81 }82 return buf;83}84 85static int snd_cs8427_select_corudata(struct snd_i2c_device *device, int udata)86{87 struct cs8427 *chip = device->private_data;88 int err;89 90 udata = udata ? CS8427_BSEL : 0;91 if (udata != (chip->regmap[CS8427_REG_CSDATABUF] & udata)) {92 chip->regmap[CS8427_REG_CSDATABUF] &= ~CS8427_BSEL;93 chip->regmap[CS8427_REG_CSDATABUF] |= udata;94 err = snd_cs8427_reg_write(device, CS8427_REG_CSDATABUF,95 chip->regmap[CS8427_REG_CSDATABUF]);96 if (err < 0)97 return err;98 }99 return 0;100}101 102static int snd_cs8427_send_corudata(struct snd_i2c_device *device,103 int udata,104 unsigned char *ndata,105 int count)106{107 struct cs8427 *chip = device->private_data;108 char *hw_data = udata ?109 chip->playback.hw_udata : chip->playback.hw_status;110 unsigned char data[32];111 int err, idx;112 113 if (!memcmp(hw_data, ndata, count))114 return 0;115 err = snd_cs8427_select_corudata(device, udata);116 if (err < 0)117 return err;118 memcpy(hw_data, ndata, count);119 if (udata) {120 memset(data, 0, sizeof(data));121 if (memcmp(hw_data, data, count) == 0) {122 chip->regmap[CS8427_REG_UDATABUF] &= ~CS8427_UBMMASK;123 chip->regmap[CS8427_REG_UDATABUF] |= CS8427_UBMZEROS |124 CS8427_EFTUI;125 err = snd_cs8427_reg_write(device, CS8427_REG_UDATABUF,126 chip->regmap[CS8427_REG_UDATABUF]);127 return err < 0 ? err : 0;128 }129 }130 data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;131 for (idx = 0; idx < count; idx++)132 data[idx + 1] = bitrev8(ndata[idx]);133 if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)134 return -EIO;135 return 1;136}137 138static void snd_cs8427_free(struct snd_i2c_device *device)139{140 kfree(device->private_data);141}142 143int snd_cs8427_init(struct snd_i2c_bus *bus,144 struct snd_i2c_device *device)145{146 static unsigned char initvals1[] = {147 CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC,148 /* CS8427_REG_CONTROL1: RMCK to OMCK, valid PCM audio, disable mutes,149 TCBL=output */150 CS8427_SWCLK | CS8427_TCBLDIR,151 /* CS8427_REG_CONTROL2: hold last valid audio sample, RMCK=256*Fs,152 normal stereo operation */153 0x00,154 /* CS8427_REG_DATAFLOW: output drivers normal operation, Tx<=serial,155 Rx=>serial */156 CS8427_TXDSERIAL | CS8427_SPDAES3RECEIVER,157 /* CS8427_REG_CLOCKSOURCE: Run off, CMCK=256*Fs,158 output time base = OMCK, input time base = recovered input clock,159 recovered input clock source is ILRCK changed to AES3INPUT160 (workaround, see snd_cs8427_reset) */161 CS8427_RXDILRCK,162 /* CS8427_REG_SERIALINPUT: Serial audio input port data format = I2S,163 24-bit, 64*Fsi */164 CS8427_SIDEL | CS8427_SILRPOL,165 /* CS8427_REG_SERIALOUTPUT: Serial audio output port data format166 = I2S, 24-bit, 64*Fsi */167 CS8427_SODEL | CS8427_SOLRPOL,168 };169 static unsigned char initvals2[] = {170 CS8427_REG_RECVERRMASK | CS8427_REG_AUTOINC,171 /* CS8427_REG_RECVERRMASK: unmask the input PLL clock, V, confidence,172 biphase, parity status bits */173 /* CS8427_UNLOCK | CS8427_V | CS8427_CONF | CS8427_BIP | CS8427_PAR,*/174 0xff, /* set everything */175 /* CS8427_REG_CSDATABUF:176 Registers 32-55 window to CS buffer177 Inhibit D->E transfers from overwriting first 5 bytes of CS data.178 Inhibit D->E transfers (all) of CS data.179 Allow E->F transfer of CS data.180 One byte mode; both A/B channels get same written CB data.181 A channel info is output to chip's EMPH* pin. */182 CS8427_CBMR | CS8427_DETCI,183 /* CS8427_REG_UDATABUF:184 Use internal buffer to transmit User (U) data.185 Chip's U pin is an output.186 Transmit all O's for user data.187 Inhibit D->E transfers.188 Inhibit E->F transfers. */189 CS8427_UD | CS8427_EFTUI | CS8427_DETUI,190 };191 struct cs8427 *chip = device->private_data;192 int err;193 unsigned char buf[24];194 195 snd_i2c_lock(bus);196 err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);197 if (err != CS8427_VER8427A) {198 /* give second chance */199 dev_warn(device->bus->card->dev,200 "invalid CS8427 signature 0x%x: let me try again...\n",201 err);202 err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);203 }204 if (err != CS8427_VER8427A) {205 snd_i2c_unlock(bus);206 dev_err(device->bus->card->dev,207 "unable to find CS8427 signature (expected 0x%x, read 0x%x),\n",208 CS8427_VER8427A, err);209 dev_err(device->bus->card->dev,210 " initialization is not completed\n");211 return -EFAULT;212 }213 /* turn off run bit while making changes to configuration */214 err = snd_cs8427_reg_write(device, CS8427_REG_CLOCKSOURCE, 0x00);215 if (err < 0)216 goto __fail;217 /* send initial values */218 memcpy(chip->regmap + (initvals1[0] & 0x7f), initvals1 + 1, 6);219 err = snd_i2c_sendbytes(device, initvals1, 7);220 if (err != 7) {221 err = err < 0 ? err : -EIO;222 goto __fail;223 }224 /* Turn off CS8427 interrupt stuff that is not used in hardware */225 memset(buf, 0, 7);226 /* from address 9 to 15 */227 buf[0] = 9; /* register */228 err = snd_i2c_sendbytes(device, buf, 7);229 if (err != 7)230 goto __fail;231 /* send transfer initialization sequence */232 memcpy(chip->regmap + (initvals2[0] & 0x7f), initvals2 + 1, 3);233 err = snd_i2c_sendbytes(device, initvals2, 4);234 if (err != 4) {235 err = err < 0 ? err : -EIO;236 goto __fail;237 }238 /* write default channel status bytes */239 put_unaligned_le32(SNDRV_PCM_DEFAULT_CON_SPDIF, buf);240 memset(buf + 4, 0, 24 - 4);241 if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0)242 goto __fail;243 memcpy(chip->playback.def_status, buf, 24);244 memcpy(chip->playback.pcm_status, buf, 24);245 snd_i2c_unlock(bus);246 247 /* turn on run bit and rock'n'roll */248 snd_cs8427_reset(device);249 250 return 0;251 252__fail:253 snd_i2c_unlock(bus);254 255 return err;256}257EXPORT_SYMBOL(snd_cs8427_init);258 259int snd_cs8427_create(struct snd_i2c_bus *bus,260 unsigned char addr,261 unsigned int reset_timeout,262 struct snd_i2c_device **r_cs8427)263{264 int err;265 struct cs8427 *chip;266 struct snd_i2c_device *device;267 268 err = snd_i2c_device_create(bus, "CS8427", CS8427_ADDR | (addr & 7),269 &device);270 if (err < 0)271 return err;272 chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL);273 if (chip == NULL) {274 snd_i2c_device_free(device);275 return -ENOMEM;276 }277 device->private_free = snd_cs8427_free;278 279 if (reset_timeout < 1)280 reset_timeout = 1;281 chip->reset_timeout = reset_timeout;282 283 err = snd_cs8427_init(bus, device);284 if (err)285 goto __fail;286 287#if 0 // it's nice for read tests288 {289 char buf[128];290 int xx;291 buf[0] = 0x81;292 snd_i2c_sendbytes(device, buf, 1);293 snd_i2c_readbytes(device, buf, 127);294 for (xx = 0; xx < 127; xx++)295 dev_dbg(device->bus->card->dev, "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);296 }297#endif298 299 if (r_cs8427)300 *r_cs8427 = device;301 return 0;302 303 __fail:304 snd_i2c_device_free(device);305 return err < 0 ? err : -EIO;306}307 308EXPORT_SYMBOL(snd_cs8427_create);309 310/*311 * Reset the chip using run bit, also lock PLL using ILRCK and312 * put back AES3INPUT. This workaround is described in latest313 * CS8427 datasheet, otherwise TXDSERIAL will not work.314 */315static void snd_cs8427_reset(struct snd_i2c_device *cs8427)316{317 struct cs8427 *chip;318 unsigned long end_time;319 int data, aes3input = 0;320 321 if (snd_BUG_ON(!cs8427))322 return;323 chip = cs8427->private_data;324 snd_i2c_lock(cs8427->bus);325 if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) ==326 CS8427_RXDAES3INPUT) /* AES3 bit is set */327 aes3input = 1;328 chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK);329 snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,330 chip->regmap[CS8427_REG_CLOCKSOURCE]);331 udelay(200);332 chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RUN | CS8427_RXDILRCK;333 snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,334 chip->regmap[CS8427_REG_CLOCKSOURCE]);335 udelay(200);336 snd_i2c_unlock(cs8427->bus);337 end_time = jiffies + chip->reset_timeout;338 while (time_after_eq(end_time, jiffies)) {339 snd_i2c_lock(cs8427->bus);340 data = snd_cs8427_reg_read(cs8427, CS8427_REG_RECVERRORS);341 snd_i2c_unlock(cs8427->bus);342 if (!(data & CS8427_UNLOCK))343 break;344 schedule_timeout_uninterruptible(1);345 }346 snd_i2c_lock(cs8427->bus);347 chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;348 if (aes3input)349 chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;350 snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,351 chip->regmap[CS8427_REG_CLOCKSOURCE]);352 snd_i2c_unlock(cs8427->bus);353}354 355static int snd_cs8427_in_status_info(struct snd_kcontrol *kcontrol,356 struct snd_ctl_elem_info *uinfo)357{358 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;359 uinfo->count = 1;360 uinfo->value.integer.min = 0;361 uinfo->value.integer.max = 255;362 return 0;363}364 365static int snd_cs8427_in_status_get(struct snd_kcontrol *kcontrol,366 struct snd_ctl_elem_value *ucontrol)367{368 struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);369 int data;370 371 snd_i2c_lock(device->bus);372 data = snd_cs8427_reg_read(device, kcontrol->private_value);373 snd_i2c_unlock(device->bus);374 if (data < 0)375 return data;376 ucontrol->value.integer.value[0] = data;377 return 0;378}379 380static int snd_cs8427_qsubcode_info(struct snd_kcontrol *kcontrol,381 struct snd_ctl_elem_info *uinfo)382{383 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;384 uinfo->count = 10;385 return 0;386}387 388static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol,389 struct snd_ctl_elem_value *ucontrol)390{391 struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);392 unsigned char reg = CS8427_REG_QSUBCODE;393 int err;394 395 snd_i2c_lock(device->bus);396 err = snd_i2c_sendbytes(device, ®, 1);397 if (err != 1) {398 dev_err(device->bus->card->dev,399 "unable to send register 0x%x byte to CS8427\n", reg);400 snd_i2c_unlock(device->bus);401 return err < 0 ? err : -EIO;402 }403 err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10);404 if (err != 10) {405 dev_err(device->bus->card->dev,406 "unable to read Q-subcode bytes from CS8427\n");407 snd_i2c_unlock(device->bus);408 return err < 0 ? err : -EIO;409 }410 snd_i2c_unlock(device->bus);411 return 0;412}413 414static int snd_cs8427_spdif_info(struct snd_kcontrol *kcontrol,415 struct snd_ctl_elem_info *uinfo)416{417 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;418 uinfo->count = 1;419 return 0;420}421 422static int snd_cs8427_spdif_get(struct snd_kcontrol *kcontrol,423 struct snd_ctl_elem_value *ucontrol)424{425 struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);426 struct cs8427 *chip = device->private_data;427 428 snd_i2c_lock(device->bus);429 memcpy(ucontrol->value.iec958.status, chip->playback.def_status, 24);430 snd_i2c_unlock(device->bus);431 return 0;432}433 434static int snd_cs8427_spdif_put(struct snd_kcontrol *kcontrol,435 struct snd_ctl_elem_value *ucontrol)436{437 struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);438 struct cs8427 *chip = device->private_data;439 unsigned char *status = kcontrol->private_value ?440 chip->playback.pcm_status : chip->playback.def_status;441 struct snd_pcm_runtime *runtime = chip->playback.substream ?442 chip->playback.substream->runtime : NULL;443 int err, change;444 445 snd_i2c_lock(device->bus);446 change = memcmp(ucontrol->value.iec958.status, status, 24) != 0;447 memcpy(status, ucontrol->value.iec958.status, 24);448 if (change && (kcontrol->private_value ?449 runtime != NULL : runtime == NULL)) {450 err = snd_cs8427_send_corudata(device, 0, status, 24);451 if (err < 0)452 change = err;453 }454 snd_i2c_unlock(device->bus);455 return change;456}457 458static int snd_cs8427_spdif_mask_info(struct snd_kcontrol *kcontrol,459 struct snd_ctl_elem_info *uinfo)460{461 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;462 uinfo->count = 1;463 return 0;464}465 466static int snd_cs8427_spdif_mask_get(struct snd_kcontrol *kcontrol,467 struct snd_ctl_elem_value *ucontrol)468{469 memset(ucontrol->value.iec958.status, 0xff, 24);470 return 0;471}472 473static const struct snd_kcontrol_new snd_cs8427_iec958_controls[] = {474{475 .iface = SNDRV_CTL_ELEM_IFACE_PCM,476 .info = snd_cs8427_in_status_info,477 .name = "IEC958 CS8427 Input Status",478 .access = (SNDRV_CTL_ELEM_ACCESS_READ |479 SNDRV_CTL_ELEM_ACCESS_VOLATILE),480 .get = snd_cs8427_in_status_get,481 .private_value = 15,482},483{484 .iface = SNDRV_CTL_ELEM_IFACE_PCM,485 .info = snd_cs8427_in_status_info,486 .name = "IEC958 CS8427 Error Status",487 .access = (SNDRV_CTL_ELEM_ACCESS_READ |488 SNDRV_CTL_ELEM_ACCESS_VOLATILE),489 .get = snd_cs8427_in_status_get,490 .private_value = 16,491},492{493 .access = SNDRV_CTL_ELEM_ACCESS_READ,494 .iface = SNDRV_CTL_ELEM_IFACE_PCM,495 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),496 .info = snd_cs8427_spdif_mask_info,497 .get = snd_cs8427_spdif_mask_get,498},499{500 .iface = SNDRV_CTL_ELEM_IFACE_PCM,501 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),502 .info = snd_cs8427_spdif_info,503 .get = snd_cs8427_spdif_get,504 .put = snd_cs8427_spdif_put,505 .private_value = 0506},507{508 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |509 SNDRV_CTL_ELEM_ACCESS_INACTIVE),510 .iface = SNDRV_CTL_ELEM_IFACE_PCM,511 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),512 .info = snd_cs8427_spdif_info,513 .get = snd_cs8427_spdif_get,514 .put = snd_cs8427_spdif_put,515 .private_value = 1516},517{518 .iface = SNDRV_CTL_ELEM_IFACE_PCM,519 .info = snd_cs8427_qsubcode_info,520 .name = "IEC958 Q-subcode Capture Default",521 .access = (SNDRV_CTL_ELEM_ACCESS_READ |522 SNDRV_CTL_ELEM_ACCESS_VOLATILE),523 .get = snd_cs8427_qsubcode_get524}};525 526int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,527 struct snd_pcm_substream *play_substream,528 struct snd_pcm_substream *cap_substream)529{530 struct cs8427 *chip = cs8427->private_data;531 struct snd_kcontrol *kctl;532 unsigned int idx;533 int err;534 535 if (snd_BUG_ON(!play_substream || !cap_substream))536 return -EINVAL;537 for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) {538 kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427);539 if (kctl == NULL)540 return -ENOMEM;541 kctl->id.device = play_substream->pcm->device;542 kctl->id.subdevice = play_substream->number;543 err = snd_ctl_add(cs8427->bus->card, kctl);544 if (err < 0)545 return err;546 if (! strcmp(kctl->id.name,547 SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM)))548 chip->playback.pcm_ctl = kctl;549 }550 551 chip->playback.substream = play_substream;552 chip->capture.substream = cap_substream;553 if (snd_BUG_ON(!chip->playback.pcm_ctl))554 return -EIO;555 return 0;556}557 558EXPORT_SYMBOL(snd_cs8427_iec958_build);559 560int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)561{562 struct cs8427 *chip;563 564 if (snd_BUG_ON(!cs8427))565 return -ENXIO;566 chip = cs8427->private_data;567 if (active) {568 memcpy(chip->playback.pcm_status,569 chip->playback.def_status, 24);570 chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;571 } else {572 chip->playback.pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;573 }574 snd_ctl_notify(cs8427->bus->card,575 SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,576 &chip->playback.pcm_ctl->id);577 return 0;578}579 580EXPORT_SYMBOL(snd_cs8427_iec958_active);581 582int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)583{584 struct cs8427 *chip;585 char *status;586 int err, reset;587 588 if (snd_BUG_ON(!cs8427))589 return -ENXIO;590 chip = cs8427->private_data;591 status = chip->playback.pcm_status;592 snd_i2c_lock(cs8427->bus);593 if (status[0] & IEC958_AES0_PROFESSIONAL) {594 status[0] &= ~IEC958_AES0_PRO_FS;595 switch (rate) {596 case 32000: status[0] |= IEC958_AES0_PRO_FS_32000; break;597 case 44100: status[0] |= IEC958_AES0_PRO_FS_44100; break;598 case 48000: status[0] |= IEC958_AES0_PRO_FS_48000; break;599 default: status[0] |= IEC958_AES0_PRO_FS_NOTID; break;600 }601 } else {602 status[3] &= ~IEC958_AES3_CON_FS;603 switch (rate) {604 case 32000: status[3] |= IEC958_AES3_CON_FS_32000; break;605 case 44100: status[3] |= IEC958_AES3_CON_FS_44100; break;606 case 48000: status[3] |= IEC958_AES3_CON_FS_48000; break;607 }608 }609 err = snd_cs8427_send_corudata(cs8427, 0, status, 24);610 if (err > 0)611 snd_ctl_notify(cs8427->bus->card,612 SNDRV_CTL_EVENT_MASK_VALUE,613 &chip->playback.pcm_ctl->id);614 reset = chip->rate != rate;615 chip->rate = rate;616 snd_i2c_unlock(cs8427->bus);617 if (reset)618 snd_cs8427_reset(cs8427);619 return err < 0 ? err : 0;620}621 622EXPORT_SYMBOL(snd_cs8427_iec958_pcm);623