Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 81569
b: refs/heads/master
c: 8432395
h: refs/heads/master
i:
  81567: 36213c1
v: v3
  • Loading branch information
Timur Tabi authored and Jaroslav Kysela committed Jan 31, 2008
1 parent c973d14 commit 20a9fa9
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 134 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b7d2a8035a382ad268aba8c0612797b4f2625f61
refs/heads/master: 8432395fd9124aa9408f61c94aa743878b4ddaf9
261 changes: 128 additions & 133 deletions trunk/sound/soc/codecs/cs4270.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,130 @@ struct cs4270_private {
unsigned int mode; /* The mode (I2S or left-justified) */
};

/* The number of MCLK/LRCK ratios supported by the CS4270 */
#define NUM_MCLK_RATIOS 9
/*
* The codec isn't really big-endian or little-endian, since the I2S
* interface requires data to be sent serially with the MSbit first.
* However, to support BE and LE I2S devices, we specify both here. That
* way, ALSA will always match the bit patterns.
*/
#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)

#ifdef USE_I2C

/* CS4270 registers addresses */
#define CS4270_CHIPID 0x01 /* Chip ID */
#define CS4270_PWRCTL 0x02 /* Power Control */
#define CS4270_MODE 0x03 /* Mode Control */
#define CS4270_FORMAT 0x04 /* Serial Format, ADC/DAC Control */
#define CS4270_TRANS 0x05 /* Transition Control */
#define CS4270_MUTE 0x06 /* Mute Control */
#define CS4270_VOLA 0x07 /* DAC Channel A Volume Control */
#define CS4270_VOLB 0x08 /* DAC Channel B Volume Control */

#define CS4270_FIRSTREG 0x01
#define CS4270_LASTREG 0x08
#define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)

/* The actual MCLK/LRCK ratios, in increasing numerical order */
static unsigned int mclk_ratios[NUM_MCLK_RATIOS] =
{64, 96, 128, 192, 256, 384, 512, 768, 1024};
/* Bit masks for the CS4270 registers */
#define CS4270_CHIPID_ID 0xF0
#define CS4270_CHIPID_REV 0x0F
#define CS4270_PWRCTL_FREEZE 0x80
#define CS4270_PWRCTL_PDN_ADC 0x20
#define CS4270_PWRCTL_PDN_DAC 0x02
#define CS4270_PWRCTL_PDN 0x01
#define CS4270_MODE_SPEED_MASK 0x30
#define CS4270_MODE_1X 0x00
#define CS4270_MODE_2X 0x10
#define CS4270_MODE_4X 0x20
#define CS4270_MODE_SLAVE 0x30
#define CS4270_MODE_DIV_MASK 0x0E
#define CS4270_MODE_DIV1 0x00
#define CS4270_MODE_DIV15 0x02
#define CS4270_MODE_DIV2 0x04
#define CS4270_MODE_DIV3 0x06
#define CS4270_MODE_DIV4 0x08
#define CS4270_MODE_POPGUARD 0x01
#define CS4270_FORMAT_FREEZE_A 0x80
#define CS4270_FORMAT_FREEZE_B 0x40
#define CS4270_FORMAT_LOOPBACK 0x20
#define CS4270_FORMAT_DAC_MASK 0x18
#define CS4270_FORMAT_DAC_LJ 0x00
#define CS4270_FORMAT_DAC_I2S 0x08
#define CS4270_FORMAT_DAC_RJ16 0x18
#define CS4270_FORMAT_DAC_RJ24 0x10
#define CS4270_FORMAT_ADC_MASK 0x01
#define CS4270_FORMAT_ADC_LJ 0x00
#define CS4270_FORMAT_ADC_I2S 0x01
#define CS4270_TRANS_ONE_VOL 0x80
#define CS4270_TRANS_SOFT 0x40
#define CS4270_TRANS_ZERO 0x20
#define CS4270_TRANS_INV_ADC_A 0x08
#define CS4270_TRANS_INV_ADC_B 0x10
#define CS4270_TRANS_INV_DAC_A 0x02
#define CS4270_TRANS_INV_DAC_B 0x04
#define CS4270_TRANS_DEEMPH 0x01
#define CS4270_MUTE_AUTO 0x20
#define CS4270_MUTE_ADC_A 0x08
#define CS4270_MUTE_ADC_B 0x10
#define CS4270_MUTE_POLARITY 0x04
#define CS4270_MUTE_DAC_A 0x01
#define CS4270_MUTE_DAC_B 0x02

/*
* Clock Ratio Selection for Master Mode with I2C enabled
*
* The data for this chart is taken from Table 5 of the CS4270 reference
* manual.
*
* This table is used to determine how to program the Mode Control register.
* It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling
* rates the CS4270 currently supports.
*
* Each element in this array corresponds to the ratios in mclk_ratios[].
* These two arrays need to be in sync.
*
* 'speed_mode' is the corresponding bit pattern to be written to the
* MODE bits of the Mode Control Register
*
* 'mclk' is the corresponding bit pattern to be wirten to the MCLK bits of
* the Mode Control Register.
*
* In situations where a single ratio is represented by multiple speed
* modes, we favor the slowest speed. E.g, for a ratio of 128, we pick
* double-speed instead of quad-speed. However, the CS4270 errata states
* that Divide-By-1.5 can cause failures, so we avoid that mode where
* possible.
*
* ERRATA: There is an errata for the CS4270 where divide-by-1.5 does not
* work if VD = 3.3V. If this effects you, select the
* CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will
* never select any sample rates that require divide-by-1.5.
*/
static struct {
unsigned int ratio;
u8 speed_mode;
u8 mclk;
} cs4270_mode_ratios[] = {
{64, CS4270_MODE_4X, CS4270_MODE_DIV1},
#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
{96, CS4270_MODE_4X, CS4270_MODE_DIV15},
#endif
{128, CS4270_MODE_2X, CS4270_MODE_DIV1},
{192, CS4270_MODE_4X, CS4270_MODE_DIV3},
{256, CS4270_MODE_1X, CS4270_MODE_DIV1},
{384, CS4270_MODE_2X, CS4270_MODE_DIV3},
{512, CS4270_MODE_1X, CS4270_MODE_DIV2},
{768, CS4270_MODE_1X, CS4270_MODE_DIV3},
{1024, CS4270_MODE_1X, CS4270_MODE_DIV4}
};

/* The number of MCLK/LRCK ratios supported by the CS4270 */
#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)

/*
* Determine the CS4270 samples rates.
Expand Down Expand Up @@ -97,7 +215,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
cs4270->mclk = freq;

for (i = 0; i < NUM_MCLK_RATIOS; i++) {
unsigned int rate = freq / mclk_ratios[i];
unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
rates |= snd_pcm_rate_to_rate_bit(rate);
if (rate < rate_min)
rate_min = rate;
Expand Down Expand Up @@ -154,80 +272,6 @@ static int cs4270_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
return ret;
}

/*
* The codec isn't really big-endian or little-endian, since the I2S
* interface requires data to be sent serially with the MSbit first.
* However, to support BE and LE I2S devices, we specify both here. That
* way, ALSA will always match the bit patterns.
*/
#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)

#ifdef USE_I2C

/* CS4270 registers addresses */
#define CS4270_CHIPID 0x01 /* Chip ID */
#define CS4270_PWRCTL 0x02 /* Power Control */
#define CS4270_MODE 0x03 /* Mode Control */
#define CS4270_FORMAT 0x04 /* Serial Format, ADC/DAC Control */
#define CS4270_TRANS 0x05 /* Transition Control */
#define CS4270_MUTE 0x06 /* Mute Control */
#define CS4270_VOLA 0x07 /* DAC Channel A Volume Control */
#define CS4270_VOLB 0x08 /* DAC Channel B Volume Control */

#define CS4270_FIRSTREG 0x01
#define CS4270_LASTREG 0x08
#define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)

/* Bit masks for the CS4270 registers */
#define CS4270_CHIPID_ID 0xF0
#define CS4270_CHIPID_REV 0x0F
#define CS4270_PWRCTL_FREEZE 0x80
#define CS4270_PWRCTL_PDN_ADC 0x20
#define CS4270_PWRCTL_PDN_DAC 0x02
#define CS4270_PWRCTL_PDN 0x01
#define CS4270_MODE_SPEED_MASK 0x30
#define CS4270_MODE_1X 0x00
#define CS4270_MODE_2X 0x10
#define CS4270_MODE_4X 0x20
#define CS4270_MODE_SLAVE 0x30
#define CS4270_MODE_DIV_MASK 0x0E
#define CS4270_MODE_DIV1 0x00
#define CS4270_MODE_DIV15 0x02
#define CS4270_MODE_DIV2 0x04
#define CS4270_MODE_DIV3 0x06
#define CS4270_MODE_DIV4 0x08
#define CS4270_MODE_POPGUARD 0x01
#define CS4270_FORMAT_FREEZE_A 0x80
#define CS4270_FORMAT_FREEZE_B 0x40
#define CS4270_FORMAT_LOOPBACK 0x20
#define CS4270_FORMAT_DAC_MASK 0x18
#define CS4270_FORMAT_DAC_LJ 0x00
#define CS4270_FORMAT_DAC_I2S 0x08
#define CS4270_FORMAT_DAC_RJ16 0x18
#define CS4270_FORMAT_DAC_RJ24 0x10
#define CS4270_FORMAT_ADC_MASK 0x01
#define CS4270_FORMAT_ADC_LJ 0x00
#define CS4270_FORMAT_ADC_I2S 0x01
#define CS4270_TRANS_ONE_VOL 0x80
#define CS4270_TRANS_SOFT 0x40
#define CS4270_TRANS_ZERO 0x20
#define CS4270_TRANS_INV_ADC_A 0x08
#define CS4270_TRANS_INV_ADC_B 0x10
#define CS4270_TRANS_INV_DAC_A 0x02
#define CS4270_TRANS_INV_DAC_B 0x04
#define CS4270_TRANS_DEEMPH 0x01
#define CS4270_MUTE_AUTO 0x20
#define CS4270_MUTE_ADC_A 0x08
#define CS4270_MUTE_ADC_B 0x10
#define CS4270_MUTE_POLARITY 0x04
#define CS4270_MUTE_DAC_A 0x01
#define CS4270_MUTE_DAC_B 0x02

/*
* A list of addresses on which this CS4270 could use. I2C addresses are
* 7 bits. For the CS4270, the upper four bits are always 1001, and the
Expand Down Expand Up @@ -314,53 +358,6 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
return 0;
}

/*
* Clock Ratio Selection for Master Mode with I2C enabled
*
* The data for this chart is taken from Table 5 of the CS4270 reference
* manual.
*
* This table is used to determine how to program the Mode Control register.
* It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling
* rates the CS4270 currently supports.
*
* Each element in this array corresponds to the ratios in mclk_ratios[].
* These two arrays need to be in sync.
*
* 'speed_mode' is the corresponding bit pattern to be written to the
* MODE bits of the Mode Control Register
*
* 'mclk' is the corresponding bit pattern to be wirten to the MCLK bits of
* the Mode Control Register.
*
* In situations where a single ratio is represented by multiple speed
* modes, we favor the slowest speed. E.g, for a ratio of 128, we pick
* double-speed instead of quad-speed. However, the CS4270 errata states
* that Divide-By-1.5 can cause failures, so we avoid that mode where
* possible.
*
* ERRATA: There is an errata for the CS4270 where divide-by-1.5 does not
* work if VD = 3.3V. If this effects you, select the
* CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will
* never select any sample rates that require divide-by-1.5.
*/
static struct {
u8 speed_mode;
u8 mclk;
} cs4270_mode_ratios[NUM_MCLK_RATIOS] = {
{CS4270_MODE_4X, CS4270_MODE_DIV1}, /* 64 */
#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
{CS4270_MODE_4X, CS4270_MODE_DIV15}, /* 96 */
#endif
{CS4270_MODE_2X, CS4270_MODE_DIV1}, /* 128 */
{CS4270_MODE_4X, CS4270_MODE_DIV3}, /* 192 */
{CS4270_MODE_1X, CS4270_MODE_DIV1}, /* 256 */
{CS4270_MODE_2X, CS4270_MODE_DIV3}, /* 384 */
{CS4270_MODE_1X, CS4270_MODE_DIV2}, /* 512 */
{CS4270_MODE_1X, CS4270_MODE_DIV3}, /* 768 */
{CS4270_MODE_1X, CS4270_MODE_DIV4} /* 1024 */
};

/*
* Program the CS4270 with the given hardware parameters.
*
Expand Down Expand Up @@ -388,7 +385,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
ratio = cs4270->mclk / rate; /* MCLK/LRCK ratio */

for (i = 0; i < NUM_MCLK_RATIOS; i++) {
if (mclk_ratios[i] == ratio)
if (cs4270_mode_ratios[i].ratio == ratio)
break;
}

Expand Down Expand Up @@ -669,7 +666,7 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
return ret;
}

#endif
#endif /* USE_I2C*/

struct snd_soc_codec_dai cs4270_dai = {
.name = "CS4270",
Expand All @@ -687,10 +684,6 @@ struct snd_soc_codec_dai cs4270_dai = {
.rates = 0,
.formats = CS4270_FORMATS,
},
.dai_ops = {
.set_sysclk = cs4270_set_dai_sysclk,
.set_fmt = cs4270_set_dai_fmt,
}
};
EXPORT_SYMBOL_GPL(cs4270_dai);

Expand Down Expand Up @@ -752,6 +745,8 @@ static int cs4270_probe(struct platform_device *pdev)
if (codec->control_data) {
/* Initialize codec ops */
cs4270_dai.ops.hw_params = cs4270_hw_params;
cs4270_dai.dai_ops.set_sysclk = cs4270_set_dai_sysclk;
cs4270_dai.dai_ops.set_fmt = cs4270_set_dai_fmt;
#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
cs4270_dai.dai_ops.digital_mute = cs4270_mute;
#endif
Expand Down

0 comments on commit 20a9fa9

Please sign in to comment.