Loading sound/soc/codecs/ad1836.c +23 −69 Original line number Diff line number Diff line Loading @@ -171,58 +171,6 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, return 0; } /* * interface to read/write ad1836 register */ #define AD1836_SPI_REG_SHFT 12 #define AD1836_SPI_READ (1 << 11) #define AD1836_SPI_VAL_MSK 0x3FF /* * write to the ad1836 register space */ static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u16 *reg_cache = codec->reg_cache; int ret = 0; if (value != reg_cache[reg]) { unsigned short buf; struct spi_transfer t = { .tx_buf = &buf, .len = 2, }; struct spi_message m; buf = (reg << AD1836_SPI_REG_SHFT) | (value & AD1836_SPI_VAL_MSK); spi_message_init(&m); spi_message_add_tail(&t, &m); ret = spi_sync(codec->control_data, &m); if (ret == 0) reg_cache[reg] = value; } return ret; } /* * read from the ad1836 register space cache */ static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { u16 *reg_cache = codec->reg_cache; if (reg >= codec->reg_cache_size) return -EINVAL; return reg_cache[reg]; } #ifdef CONFIG_PM static int ad1836_soc_suspend(struct platform_device *pdev, pm_message_t state) Loading @@ -231,10 +179,10 @@ static int ad1836_soc_suspend(struct platform_device *pdev, struct snd_soc_codec *codec = socdev->card->codec; /* reset clock control mode */ u16 adc_ctrl2 = codec->read(codec, AD1836_ADC_CTRL2); u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK; return codec->write(codec, AD1836_ADC_CTRL2, adc_ctrl2); return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2); } static int ad1836_soc_resume(struct platform_device *pdev) Loading @@ -243,10 +191,10 @@ static int ad1836_soc_resume(struct platform_device *pdev) struct snd_soc_codec *codec = socdev->card->codec; /* restore clock control mode */ u16 adc_ctrl2 = codec->read(codec, AD1836_ADC_CTRL2); u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); adc_ctrl2 |= AD1836_ADC_AUX; return codec->write(codec, AD1836_ADC_CTRL2, adc_ctrl2); return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2); } #else #define ad1836_soc_suspend NULL Loading Loading @@ -336,32 +284,38 @@ static int ad1836_register(struct ad1836_priv *ad1836) codec->owner = THIS_MODULE; codec->dai = &ad1836_dai; codec->num_dai = 1; codec->write = ad1836_write_reg; codec->read = ad1836_read_reg_cache; INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); ad1836_dai.dev = codec->dev; ad1836_codec = codec; ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI); if (ret < 0) { dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); kfree(ad1836); return ret; } /* default setting for ad1836 */ /* de-emphasis: 48kHz, power-on dac */ codec->write(codec, AD1836_DAC_CTRL1, 0x300); snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300); /* unmute dac channels */ codec->write(codec, AD1836_DAC_CTRL2, 0x0); snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0); /* high-pass filter enable, power-on adc */ codec->write(codec, AD1836_ADC_CTRL1, 0x100); snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100); /* unmute adc channles, adc aux mode */ codec->write(codec, AD1836_ADC_CTRL2, 0x180); snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180); /* left/right diff:PGA/MUX */ codec->write(codec, AD1836_ADC_CTRL3, 0x3A); snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); /* volume */ codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF); ret = snd_soc_register_codec(codec); if (ret != 0) { Loading sound/soc/soc-cache.c +67 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,68 @@ #include <linux/spi/spi.h> #include <sound/soc.h> static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, unsigned int reg) { u16 *cache = codec->reg_cache; if (reg >= codec->reg_cache_size) return -1; return cache[reg]; } static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u16 *cache = codec->reg_cache; u8 data[2]; int ret; BUG_ON(codec->volatile_register); data[0] = (reg << 4) | ((value >> 8) & 0x000f); data[1] = value & 0x00ff; if (reg < codec->reg_cache_size) cache[reg] = value; ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) return 0; if (ret < 0) return ret; else return -EIO; } #if defined(CONFIG_SPI_MASTER) static int snd_soc_4_12_spi_write(void *control_data, const char *data, int len) { struct spi_device *spi = control_data; struct spi_transfer t; struct spi_message m; u8 msg[2]; if (len <= 0) return 0; msg[0] = data[1]; msg[1] = data[0]; spi_message_init(&m); memset(&t, 0, (sizeof t)); t.tx_buf = &msg[0]; t.len = len; spi_message_add_tail(&t, &m); spi_sync(spi, &m); return len; } #else #define snd_soc_4_12_spi_write NULL #endif static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, unsigned int reg) { Loading Loading @@ -179,6 +241,11 @@ static struct { unsigned int (*read)(struct snd_soc_codec *, unsigned int); unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); } io_types[] = { { .addr_bits = 4, .data_bits = 12, .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, .spi_write = snd_soc_4_12_spi_write, }, { .addr_bits = 7, .data_bits = 9, .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, Loading Loading
sound/soc/codecs/ad1836.c +23 −69 Original line number Diff line number Diff line Loading @@ -171,58 +171,6 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, return 0; } /* * interface to read/write ad1836 register */ #define AD1836_SPI_REG_SHFT 12 #define AD1836_SPI_READ (1 << 11) #define AD1836_SPI_VAL_MSK 0x3FF /* * write to the ad1836 register space */ static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u16 *reg_cache = codec->reg_cache; int ret = 0; if (value != reg_cache[reg]) { unsigned short buf; struct spi_transfer t = { .tx_buf = &buf, .len = 2, }; struct spi_message m; buf = (reg << AD1836_SPI_REG_SHFT) | (value & AD1836_SPI_VAL_MSK); spi_message_init(&m); spi_message_add_tail(&t, &m); ret = spi_sync(codec->control_data, &m); if (ret == 0) reg_cache[reg] = value; } return ret; } /* * read from the ad1836 register space cache */ static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { u16 *reg_cache = codec->reg_cache; if (reg >= codec->reg_cache_size) return -EINVAL; return reg_cache[reg]; } #ifdef CONFIG_PM static int ad1836_soc_suspend(struct platform_device *pdev, pm_message_t state) Loading @@ -231,10 +179,10 @@ static int ad1836_soc_suspend(struct platform_device *pdev, struct snd_soc_codec *codec = socdev->card->codec; /* reset clock control mode */ u16 adc_ctrl2 = codec->read(codec, AD1836_ADC_CTRL2); u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK; return codec->write(codec, AD1836_ADC_CTRL2, adc_ctrl2); return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2); } static int ad1836_soc_resume(struct platform_device *pdev) Loading @@ -243,10 +191,10 @@ static int ad1836_soc_resume(struct platform_device *pdev) struct snd_soc_codec *codec = socdev->card->codec; /* restore clock control mode */ u16 adc_ctrl2 = codec->read(codec, AD1836_ADC_CTRL2); u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); adc_ctrl2 |= AD1836_ADC_AUX; return codec->write(codec, AD1836_ADC_CTRL2, adc_ctrl2); return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2); } #else #define ad1836_soc_suspend NULL Loading Loading @@ -336,32 +284,38 @@ static int ad1836_register(struct ad1836_priv *ad1836) codec->owner = THIS_MODULE; codec->dai = &ad1836_dai; codec->num_dai = 1; codec->write = ad1836_write_reg; codec->read = ad1836_read_reg_cache; INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); ad1836_dai.dev = codec->dev; ad1836_codec = codec; ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI); if (ret < 0) { dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); kfree(ad1836); return ret; } /* default setting for ad1836 */ /* de-emphasis: 48kHz, power-on dac */ codec->write(codec, AD1836_DAC_CTRL1, 0x300); snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300); /* unmute dac channels */ codec->write(codec, AD1836_DAC_CTRL2, 0x0); snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0); /* high-pass filter enable, power-on adc */ codec->write(codec, AD1836_ADC_CTRL1, 0x100); snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100); /* unmute adc channles, adc aux mode */ codec->write(codec, AD1836_ADC_CTRL2, 0x180); snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180); /* left/right diff:PGA/MUX */ codec->write(codec, AD1836_ADC_CTRL3, 0x3A); snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); /* volume */ codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF); snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF); ret = snd_soc_register_codec(codec); if (ret != 0) { Loading
sound/soc/soc-cache.c +67 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,68 @@ #include <linux/spi/spi.h> #include <sound/soc.h> static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, unsigned int reg) { u16 *cache = codec->reg_cache; if (reg >= codec->reg_cache_size) return -1; return cache[reg]; } static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u16 *cache = codec->reg_cache; u8 data[2]; int ret; BUG_ON(codec->volatile_register); data[0] = (reg << 4) | ((value >> 8) & 0x000f); data[1] = value & 0x00ff; if (reg < codec->reg_cache_size) cache[reg] = value; ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) return 0; if (ret < 0) return ret; else return -EIO; } #if defined(CONFIG_SPI_MASTER) static int snd_soc_4_12_spi_write(void *control_data, const char *data, int len) { struct spi_device *spi = control_data; struct spi_transfer t; struct spi_message m; u8 msg[2]; if (len <= 0) return 0; msg[0] = data[1]; msg[1] = data[0]; spi_message_init(&m); memset(&t, 0, (sizeof t)); t.tx_buf = &msg[0]; t.len = len; spi_message_add_tail(&t, &m); spi_sync(spi, &m); return len; } #else #define snd_soc_4_12_spi_write NULL #endif static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, unsigned int reg) { Loading Loading @@ -179,6 +241,11 @@ static struct { unsigned int (*read)(struct snd_soc_codec *, unsigned int); unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); } io_types[] = { { .addr_bits = 4, .data_bits = 12, .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, .spi_write = snd_soc_4_12_spi_write, }, { .addr_bits = 7, .data_bits = 9, .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, Loading