sound/i2c/cs8427.c

Source file repositories/reference/linux-study-clean/sound/i2c/cs8427.c

File Facts

System
Linux kernel
Corpus path
sound/i2c/cs8427.c
Extension
.c
Size
18045 bytes
Lines
623
Domain
Driver Families
Bucket
sound/i2c
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cs8427_stream {
	struct snd_pcm_substream *substream;
	char hw_status[24];		/* hardware status */
	char def_status[24];		/* default status */
	char pcm_status[24];		/* PCM private status */
	char hw_udata[32];
	struct snd_kcontrol *pcm_ctl;
};

struct cs8427 {
	unsigned char regmap[0x14];	/* map of first 1 + 13 registers */
	unsigned int rate;
	unsigned int reset_timeout;
	struct cs8427_stream playback;
	struct cs8427_stream capture;
};

int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
			 unsigned char val)
{
	int err;
	unsigned char buf[2];

	buf[0] = reg & 0x7f;
	buf[1] = val;
	err = snd_i2c_sendbytes(device, buf, 2);
	if (err != 2) {
		dev_err(device->bus->card->dev,
			"unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n",
			buf[0], buf[1], err);
		return err < 0 ? err : -EIO;
	}
	return 0;
}

EXPORT_SYMBOL(snd_cs8427_reg_write);

static int snd_cs8427_reg_read(struct snd_i2c_device *device, unsigned char reg)
{
	int err;
	unsigned char buf;

	err = snd_i2c_sendbytes(device, &reg, 1);
	if (err != 1) {
		dev_err(device->bus->card->dev,
			"unable to send register 0x%x byte to CS8427\n", reg);
		return err < 0 ? err : -EIO;
	}
	err = snd_i2c_readbytes(device, &buf, 1);
	if (err != 1) {
		dev_err(device->bus->card->dev,
			"unable to read register 0x%x byte from CS8427\n", reg);
		return err < 0 ? err : -EIO;
	}
	return buf;
}

static int snd_cs8427_select_corudata(struct snd_i2c_device *device, int udata)
{
	struct cs8427 *chip = device->private_data;
	int err;

	udata = udata ? CS8427_BSEL : 0;
	if (udata != (chip->regmap[CS8427_REG_CSDATABUF] & udata)) {
		chip->regmap[CS8427_REG_CSDATABUF] &= ~CS8427_BSEL;
		chip->regmap[CS8427_REG_CSDATABUF] |= udata;
		err = snd_cs8427_reg_write(device, CS8427_REG_CSDATABUF,
					   chip->regmap[CS8427_REG_CSDATABUF]);
		if (err < 0)
			return err;
	}
	return 0;
}

static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
				    int udata,
				    unsigned char *ndata,
				    int count)
{
	struct cs8427 *chip = device->private_data;
	char *hw_data = udata ?
		chip->playback.hw_udata : chip->playback.hw_status;
	unsigned char data[32];
	int err, idx;

	if (!memcmp(hw_data, ndata, count))
		return 0;
	err = snd_cs8427_select_corudata(device, udata);
	if (err < 0)
		return err;

Annotation

Implementation Notes