Merge branch 'for-2.6.38' into for-2.6.39
This commit is contained in:
		
						commit
						3e8e2cc45c
					
				| @ -27,42 +27,38 @@ ASoC Codec driver breakdown | |||||||
| 
 | 
 | ||||||
| 1 - Codec DAI and PCM configuration | 1 - Codec DAI and PCM configuration | ||||||
| ----------------------------------- | ----------------------------------- | ||||||
| Each codec driver must have a struct snd_soc_codec_dai to define its DAI and | Each codec driver must have a struct snd_soc_dai_driver to define its DAI and | ||||||
| PCM capabilities and operations. This struct is exported so that it can be | PCM capabilities and operations. This struct is exported so that it can be | ||||||
| registered with the core by your machine driver. | registered with the core by your machine driver. | ||||||
| 
 | 
 | ||||||
| e.g. | e.g. | ||||||
| 
 | 
 | ||||||
| struct snd_soc_codec_dai wm8731_dai = { | static struct snd_soc_dai_ops wm8731_dai_ops = { | ||||||
| 	.name = "WM8731", | 	.prepare	= wm8731_pcm_prepare, | ||||||
| 	/* playback capabilities */ | 	.hw_params	= wm8731_hw_params, | ||||||
|  | 	.shutdown	= wm8731_shutdown, | ||||||
|  | 	.digital_mute	= wm8731_mute, | ||||||
|  | 	.set_sysclk	= wm8731_set_dai_sysclk, | ||||||
|  | 	.set_fmt	= wm8731_set_dai_fmt, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct snd_soc_dai_driver wm8731_dai = { | ||||||
|  | 	.name = "wm8731-hifi", | ||||||
| 	.playback = { | 	.playback = { | ||||||
| 		.stream_name = "Playback", | 		.stream_name = "Playback", | ||||||
| 		.channels_min = 1, | 		.channels_min = 1, | ||||||
| 		.channels_max = 2, | 		.channels_max = 2, | ||||||
| 		.rates = WM8731_RATES, | 		.rates = WM8731_RATES, | ||||||
| 		.formats = WM8731_FORMATS,}, | 		.formats = WM8731_FORMATS,}, | ||||||
| 	/* capture capabilities */ |  | ||||||
| 	.capture = { | 	.capture = { | ||||||
| 		.stream_name = "Capture", | 		.stream_name = "Capture", | ||||||
| 		.channels_min = 1, | 		.channels_min = 1, | ||||||
| 		.channels_max = 2, | 		.channels_max = 2, | ||||||
| 		.rates = WM8731_RATES, | 		.rates = WM8731_RATES, | ||||||
| 		.formats = WM8731_FORMATS,}, | 		.formats = WM8731_FORMATS,}, | ||||||
| 	/* pcm operations - see section 4 below */ | 	.ops = &wm8731_dai_ops, | ||||||
| 	.ops = { | 	.symmetric_rates = 1, | ||||||
| 		.prepare = wm8731_pcm_prepare, |  | ||||||
| 		.hw_params = wm8731_hw_params, |  | ||||||
| 		.shutdown = wm8731_shutdown, |  | ||||||
| 	}, |  | ||||||
| 	/* DAI operations - see DAI.txt */ |  | ||||||
| 	.dai_ops = { |  | ||||||
| 		.digital_mute = wm8731_mute, |  | ||||||
| 		.set_sysclk = wm8731_set_dai_sysclk, |  | ||||||
| 		.set_fmt = wm8731_set_dai_fmt, |  | ||||||
| 	} |  | ||||||
| }; | }; | ||||||
| EXPORT_SYMBOL_GPL(wm8731_dai); |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 2 - Codec control IO | 2 - Codec control IO | ||||||
| @ -186,13 +182,14 @@ when the mute is applied or freed. | |||||||
| 
 | 
 | ||||||
| i.e. | i.e. | ||||||
| 
 | 
 | ||||||
| static int wm8974_mute(struct snd_soc_codec *codec, | static int wm8974_mute(struct snd_soc_dai *dai, int mute) | ||||||
| 	struct snd_soc_codec_dai *dai, int mute) |  | ||||||
| { | { | ||||||
| 	u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf; | 	struct snd_soc_codec *codec = dai->codec; | ||||||
| 	if(mute) | 	u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf; | ||||||
| 		wm8974_write(codec, WM8974_DAC, mute_reg | 0x40); | 
 | ||||||
|  | 	if (mute) | ||||||
|  | 		snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40); | ||||||
| 	else | 	else | ||||||
| 		wm8974_write(codec, WM8974_DAC, mute_reg); | 		snd_soc_write(codec, WM8974_DAC, mute_reg); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -12,6 +12,8 @@ the following struct:- | |||||||
| struct snd_soc_card { | struct snd_soc_card { | ||||||
| 	char *name; | 	char *name; | ||||||
| 
 | 
 | ||||||
|  | 	... | ||||||
|  | 
 | ||||||
| 	int (*probe)(struct platform_device *pdev); | 	int (*probe)(struct platform_device *pdev); | ||||||
| 	int (*remove)(struct platform_device *pdev); | 	int (*remove)(struct platform_device *pdev); | ||||||
| 
 | 
 | ||||||
| @ -22,12 +24,13 @@ struct snd_soc_card { | |||||||
| 	int (*resume_pre)(struct platform_device *pdev); | 	int (*resume_pre)(struct platform_device *pdev); | ||||||
| 	int (*resume_post)(struct platform_device *pdev); | 	int (*resume_post)(struct platform_device *pdev); | ||||||
| 
 | 
 | ||||||
| 	/* machine stream operations */ | 	... | ||||||
| 	struct snd_soc_ops *ops; |  | ||||||
| 
 | 
 | ||||||
| 	/* CPU <--> Codec DAI links  */ | 	/* CPU <--> Codec DAI links  */ | ||||||
| 	struct snd_soc_dai_link *dai_link; | 	struct snd_soc_dai_link *dai_link; | ||||||
| 	int num_links; | 	int num_links; | ||||||
|  | 
 | ||||||
|  | 	... | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| probe()/remove() | probe()/remove() | ||||||
| @ -42,11 +45,6 @@ of any machine audio tasks that have to be done before or after the codec, DAIs | |||||||
| and DMA is suspended and resumed. Optional. | and DMA is suspended and resumed. Optional. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Machine operations |  | ||||||
| ------------------ |  | ||||||
| The machine specific audio operations can be set here. Again this is optional. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| Machine DAI Configuration | Machine DAI Configuration | ||||||
| ------------------------- | ------------------------- | ||||||
| The machine DAI configuration glues all the codec and CPU DAIs together. It can | The machine DAI configuration glues all the codec and CPU DAIs together. It can | ||||||
| @ -61,8 +59,10 @@ struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. | |||||||
| static struct snd_soc_dai_link corgi_dai = { | static struct snd_soc_dai_link corgi_dai = { | ||||||
| 	.name = "WM8731", | 	.name = "WM8731", | ||||||
| 	.stream_name = "WM8731", | 	.stream_name = "WM8731", | ||||||
| 	.cpu_dai = &pxa_i2s_dai, | 	.cpu_dai_name = "pxa-is2-dai", | ||||||
| 	.codec_dai = &wm8731_dai, | 	.codec_dai_name = "wm8731-hifi", | ||||||
|  | 	.platform_name = "pxa-pcm-audio", | ||||||
|  | 	.codec_name = "wm8713-codec.0-001a", | ||||||
| 	.init = corgi_wm8731_init, | 	.init = corgi_wm8731_init, | ||||||
| 	.ops = &corgi_ops, | 	.ops = &corgi_ops, | ||||||
| }; | }; | ||||||
| @ -77,26 +77,6 @@ static struct snd_soc_card snd_soc_corgi = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Machine Audio Subsystem |  | ||||||
| ----------------------- |  | ||||||
| 
 |  | ||||||
| The machine soc device glues the platform, machine and codec driver together. |  | ||||||
| Private data can also be set here. e.g. |  | ||||||
| 
 |  | ||||||
| /* corgi audio private data */ |  | ||||||
| static struct wm8731_setup_data corgi_wm8731_setup = { |  | ||||||
| 	.i2c_address = 0x1b, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* corgi audio subsystem */ |  | ||||||
| static struct snd_soc_device corgi_snd_devdata = { |  | ||||||
| 	.machine = &snd_soc_corgi, |  | ||||||
| 	.platform = &pxa2xx_soc_platform, |  | ||||||
| 	.codec_dev = &soc_codec_dev_wm8731, |  | ||||||
| 	.codec_data = &corgi_wm8731_setup, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| Machine Power Map | Machine Power Map | ||||||
| ----------------- | ----------------- | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,9 +20,10 @@ struct snd_soc_ops { | |||||||
| 	int (*trigger)(struct snd_pcm_substream *, int); | 	int (*trigger)(struct snd_pcm_substream *, int); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| The platform driver exports its DMA functionality via struct snd_soc_platform:- | The platform driver exports its DMA functionality via struct | ||||||
|  | snd_soc_platform_driver:- | ||||||
| 
 | 
 | ||||||
| struct snd_soc_platform { | struct snd_soc_platform_driver { | ||||||
| 	char *name; | 	char *name; | ||||||
| 
 | 
 | ||||||
| 	int (*probe)(struct platform_device *pdev); | 	int (*probe)(struct platform_device *pdev); | ||||||
| @ -34,6 +35,13 @@ struct snd_soc_platform { | |||||||
| 	int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *); | 	int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *); | ||||||
| 	void (*pcm_free)(struct snd_pcm *); | 	void (*pcm_free)(struct snd_pcm *); | ||||||
| 
 | 
 | ||||||
|  | 	/* | ||||||
|  | 	 * For platform caused delay reporting. | ||||||
|  | 	 * Optional. | ||||||
|  | 	 */ | ||||||
|  | 	snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *, | ||||||
|  | 		struct snd_soc_dai *); | ||||||
|  | 
 | ||||||
| 	/* platform stream ops */ | 	/* platform stream ops */ | ||||||
| 	struct snd_pcm_ops *pcm_ops; | 	struct snd_pcm_ops *pcm_ops; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -168,6 +168,9 @@ config SND_SOC_L3 | |||||||
| config SND_SOC_DA7210 | config SND_SOC_DA7210 | ||||||
|         tristate |         tristate | ||||||
| 
 | 
 | ||||||
|  | config SND_SOC_DMIC | ||||||
|  | 	tristate | ||||||
|  | 
 | ||||||
| config SND_SOC_MAX98088 | config SND_SOC_MAX98088 | ||||||
|        tristate |        tristate | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ snd-soc-cs42l51-objs := cs42l51.o | |||||||
| snd-soc-cs4270-objs := cs4270.o | snd-soc-cs4270-objs := cs4270.o | ||||||
| snd-soc-cx20442-objs := cx20442.o | snd-soc-cx20442-objs := cx20442.o | ||||||
| snd-soc-da7210-objs := da7210.o | snd-soc-da7210-objs := da7210.o | ||||||
|  | snd-soc-dmic-objs := dmic.o | ||||||
| snd-soc-l3-objs := l3.o | snd-soc-l3-objs := l3.o | ||||||
| snd-soc-max98088-objs := max98088.o | snd-soc-max98088-objs := max98088.o | ||||||
| snd-soc-pcm3008-objs := pcm3008.o | snd-soc-pcm3008-objs := pcm3008.o | ||||||
| @ -93,6 +94,7 @@ obj-$(CONFIG_SND_SOC_CS42L51)	+= snd-soc-cs42l51.o | |||||||
| obj-$(CONFIG_SND_SOC_CS4270)	+= snd-soc-cs4270.o | obj-$(CONFIG_SND_SOC_CS4270)	+= snd-soc-cs4270.o | ||||||
| obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o | obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o | ||||||
| obj-$(CONFIG_SND_SOC_DA7210)	+= snd-soc-da7210.o | obj-$(CONFIG_SND_SOC_DA7210)	+= snd-soc-da7210.o | ||||||
|  | obj-$(CONFIG_SND_SOC_DMIC)	+= snd-soc-dmic.o | ||||||
| obj-$(CONFIG_SND_SOC_L3)	+= snd-soc-l3.o | obj-$(CONFIG_SND_SOC_L3)	+= snd-soc-l3.o | ||||||
| obj-$(CONFIG_SND_SOC_JZ4740_CODEC)	+= snd-soc-jz4740-codec.o | obj-$(CONFIG_SND_SOC_JZ4740_CODEC)	+= snd-soc-jz4740-codec.o | ||||||
| obj-$(CONFIG_SND_SOC_MAX98088)	+= snd-soc-max98088.o | obj-$(CONFIG_SND_SOC_MAX98088)	+= snd-soc-max98088.o | ||||||
|  | |||||||
| @ -106,6 +106,21 @@ | |||||||
| #define CS4270_MUTE_DAC_A	0x01 | #define CS4270_MUTE_DAC_A	0x01 | ||||||
| #define CS4270_MUTE_DAC_B	0x02 | #define CS4270_MUTE_DAC_B	0x02 | ||||||
| 
 | 
 | ||||||
|  | /* Power-on default values for the registers
 | ||||||
|  |  * | ||||||
|  |  * This array contains the power-on default values of the registers, with the | ||||||
|  |  * exception of the "CHIPID" register (01h).  The lower four bits of that | ||||||
|  |  * register contain the hardware revision, so it is treated as volatile. | ||||||
|  |  * | ||||||
|  |  * Also note that on the CS4270, the first readable register is 1, but ASoC | ||||||
|  |  * assumes the first register is 0.  Therfore, the array must have an entry for | ||||||
|  |  * register 0, but we use cs4270_reg_is_readable() to tell ASoC that it can't | ||||||
|  |  * be read. | ||||||
|  |  */ | ||||||
|  | static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = { | ||||||
|  | 	0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| static const char *supply_names[] = { | static const char *supply_names[] = { | ||||||
| 	"va", "vd", "vlc" | 	"va", "vd", "vlc" | ||||||
| }; | }; | ||||||
| @ -178,6 +193,20 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = { | |||||||
| /* The number of MCLK/LRCK ratios supported by the CS4270 */ | /* The number of MCLK/LRCK ratios supported by the CS4270 */ | ||||||
| #define NUM_MCLK_RATIOS		ARRAY_SIZE(cs4270_mode_ratios) | #define NUM_MCLK_RATIOS		ARRAY_SIZE(cs4270_mode_ratios) | ||||||
| 
 | 
 | ||||||
|  | static int cs4270_reg_is_readable(unsigned int reg) | ||||||
|  | { | ||||||
|  | 	return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int cs4270_reg_is_volatile(unsigned int reg) | ||||||
|  | { | ||||||
|  | 	/* Unreadable registers are considered volatile */ | ||||||
|  | 	if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	return reg == CS4270_CHIPID; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * cs4270_set_dai_sysclk - determine the CS4270 samples rates. |  * cs4270_set_dai_sysclk - determine the CS4270 samples rates. | ||||||
|  * @codec_dai: the codec DAI |  * @codec_dai: the codec DAI | ||||||
| @ -262,97 +291,6 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 |  | ||||||
|  * cs4270_fill_cache - pre-fill the CS4270 register cache. |  | ||||||
|  * @codec: the codec for this CS4270 |  | ||||||
|  * |  | ||||||
|  * This function fills in the CS4270 register cache by reading the register |  | ||||||
|  * values from the hardware. |  | ||||||
|  * |  | ||||||
|  * This CS4270 registers are cached to avoid excessive I2C I/O operations. |  | ||||||
|  * After the initial read to pre-fill the cache, the CS4270 never updates |  | ||||||
|  * the register values, so we won't have a cache coherency problem. |  | ||||||
|  * |  | ||||||
|  * We use the auto-increment feature of the CS4270 to read all registers in |  | ||||||
|  * one shot. |  | ||||||
|  */ |  | ||||||
| static int cs4270_fill_cache(struct snd_soc_codec *codec) |  | ||||||
| { |  | ||||||
| 	u8 *cache = codec->reg_cache; |  | ||||||
| 	struct i2c_client *i2c_client = codec->control_data; |  | ||||||
| 	s32 length; |  | ||||||
| 
 |  | ||||||
| 	length = i2c_smbus_read_i2c_block_data(i2c_client, |  | ||||||
| 		CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache); |  | ||||||
| 
 |  | ||||||
| 	if (length != CS4270_NUMREGS) { |  | ||||||
| 		dev_err(codec->dev, "i2c read failure, addr=0x%x\n", |  | ||||||
| 		       i2c_client->addr); |  | ||||||
| 		return -EIO; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * cs4270_read_reg_cache - read from the CS4270 register cache. |  | ||||||
|  * @codec: the codec for this CS4270 |  | ||||||
|  * @reg: the register to read |  | ||||||
|  * |  | ||||||
|  * This function returns the value for a given register.  It reads only from |  | ||||||
|  * the register cache, not the hardware itself. |  | ||||||
|  * |  | ||||||
|  * This CS4270 registers are cached to avoid excessive I2C I/O operations. |  | ||||||
|  * After the initial read to pre-fill the cache, the CS4270 never updates |  | ||||||
|  * the register values, so we won't have a cache coherency problem. |  | ||||||
|  */ |  | ||||||
| static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, |  | ||||||
| 	unsigned int reg) |  | ||||||
| { |  | ||||||
| 	u8 *cache = codec->reg_cache; |  | ||||||
| 
 |  | ||||||
| 	if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) |  | ||||||
| 		return -EIO; |  | ||||||
| 
 |  | ||||||
| 	return cache[reg - CS4270_FIRSTREG]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * cs4270_i2c_write - write to a CS4270 register via the I2C bus. |  | ||||||
|  * @codec: the codec for this CS4270 |  | ||||||
|  * @reg: the register to write |  | ||||||
|  * @value: the value to write to the register |  | ||||||
|  * |  | ||||||
|  * This function writes the given value to the given CS4270 register, and |  | ||||||
|  * also updates the register cache. |  | ||||||
|  * |  | ||||||
|  * Note that we don't use the hw_write function pointer of snd_soc_codec. |  | ||||||
|  * That's because it's too clunky: the hw_write_t prototype does not match |  | ||||||
|  * i2c_smbus_write_byte_data(), and it's just another layer of overhead. |  | ||||||
|  */ |  | ||||||
| static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg, |  | ||||||
| 			    unsigned int value) |  | ||||||
| { |  | ||||||
| 	u8 *cache = codec->reg_cache; |  | ||||||
| 
 |  | ||||||
| 	if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) |  | ||||||
| 		return -EIO; |  | ||||||
| 
 |  | ||||||
| 	/* Only perform an I2C operation if the new value is different */ |  | ||||||
| 	if (cache[reg - CS4270_FIRSTREG] != value) { |  | ||||||
| 		struct i2c_client *client = codec->control_data; |  | ||||||
| 		if (i2c_smbus_write_byte_data(client, reg, value)) { |  | ||||||
| 			dev_err(codec->dev, "i2c write failed\n"); |  | ||||||
| 			return -EIO; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		/* We've written to the hardware, so update the cache */ |  | ||||||
| 		cache[reg - CS4270_FIRSTREG] = value; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * cs4270_hw_params - program the CS4270 with the given hardware parameters. |  * cs4270_hw_params - program the CS4270 with the given hardware parameters. | ||||||
|  * @substream: the audio stream |  * @substream: the audio stream | ||||||
| @ -550,15 +488,16 @@ static struct snd_soc_dai_driver cs4270_dai = { | |||||||
| static int cs4270_probe(struct snd_soc_codec *codec) | static int cs4270_probe(struct snd_soc_codec *codec) | ||||||
| { | { | ||||||
| 	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | ||||||
| 	int i, ret, reg; | 	int i, ret; | ||||||
| 
 | 
 | ||||||
| 	codec->control_data = cs4270->control_data; | 	codec->control_data = cs4270->control_data; | ||||||
| 
 | 
 | ||||||
| 	/* The I2C interface is set up, so pre-fill our register cache */ | 	/* Tell ASoC what kind of I/O to use to read the registers.  ASoC will
 | ||||||
| 
 | 	 * then do the I2C transactions itself. | ||||||
| 	ret = cs4270_fill_cache(codec); | 	 */ | ||||||
|  | 	ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type); | ||||||
| 	if (ret < 0) { | 	if (ret < 0) { | ||||||
| 		dev_err(codec->dev, "failed to fill register cache\n"); | 		dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret); | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -567,10 +506,7 @@ static int cs4270_probe(struct snd_soc_codec *codec) | |||||||
| 	 * this feature disabled by default.  An application (e.g. alsactl) can | 	 * this feature disabled by default.  An application (e.g. alsactl) can | ||||||
| 	 * re-enabled it by using the controls. | 	 * re-enabled it by using the controls. | ||||||
| 	 */ | 	 */ | ||||||
| 
 | 	ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0); | ||||||
| 	reg = cs4270_read_reg_cache(codec, CS4270_MUTE); |  | ||||||
| 	reg &= ~CS4270_MUTE_AUTO; |  | ||||||
| 	ret = cs4270_i2c_write(codec, CS4270_MUTE, reg); |  | ||||||
| 	if (ret < 0) { | 	if (ret < 0) { | ||||||
| 		dev_err(codec->dev, "i2c write failed\n"); | 		dev_err(codec->dev, "i2c write failed\n"); | ||||||
| 		return ret; | 		return ret; | ||||||
| @ -581,10 +517,8 @@ static int cs4270_probe(struct snd_soc_codec *codec) | |||||||
| 	 * playback has started.  An application (e.g. alsactl) can | 	 * playback has started.  An application (e.g. alsactl) can | ||||||
| 	 * re-enabled it by using the controls. | 	 * re-enabled it by using the controls. | ||||||
| 	 */ | 	 */ | ||||||
| 
 | 	ret = snd_soc_update_bits(codec, CS4270_TRANS, | ||||||
| 	reg = cs4270_read_reg_cache(codec, CS4270_TRANS); | 		CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0); | ||||||
| 	reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); |  | ||||||
| 	ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); |  | ||||||
| 	if (ret < 0) { | 	if (ret < 0) { | ||||||
| 		dev_err(codec->dev, "i2c write failed\n"); | 		dev_err(codec->dev, "i2c write failed\n"); | ||||||
| 		return ret; | 		return ret; | ||||||
| @ -707,15 +641,16 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec) | |||||||
|  * Assign this variable to the codec_dev field of the machine driver's |  * Assign this variable to the codec_dev field of the machine driver's | ||||||
|  * snd_soc_device structure. |  * snd_soc_device structure. | ||||||
|  */ |  */ | ||||||
| static struct snd_soc_codec_driver soc_codec_device_cs4270 = { | static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { | ||||||
| 	.probe =		cs4270_probe, | 	.probe =		cs4270_probe, | ||||||
| 	.remove =		cs4270_remove, | 	.remove =		cs4270_remove, | ||||||
| 	.suspend =		cs4270_soc_suspend, | 	.suspend =		cs4270_soc_suspend, | ||||||
| 	.resume =		cs4270_soc_resume, | 	.resume =		cs4270_soc_resume, | ||||||
| 	.read = cs4270_read_reg_cache, | 	.volatile_register =	cs4270_reg_is_volatile, | ||||||
| 	.write = cs4270_i2c_write, | 	.readable_register =	cs4270_reg_is_readable, | ||||||
| 	.reg_cache_size = CS4270_NUMREGS, | 	.reg_cache_size =	CS4270_LASTREG + 1, | ||||||
| 	.reg_word_size =	sizeof(u8), | 	.reg_word_size =	sizeof(u8), | ||||||
|  | 	.reg_cache_default =	cs4270_default_reg_cache, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | |||||||
							
								
								
									
										81
									
								
								sound/soc/codecs/dmic.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								sound/soc/codecs/dmic.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,81 @@ | |||||||
|  | /*
 | ||||||
|  |  * dmic.c  --  SoC audio for Generic Digital MICs | ||||||
|  |  * | ||||||
|  |  * Author: Liam Girdwood <lrg@slimlogic.co.uk> | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or | ||||||
|  |  * modify it under the terms of the GNU General Public License | ||||||
|  |  * version 2 as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, but | ||||||
|  |  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||||
|  |  * General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program; if not, write to the Free Software | ||||||
|  |  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||||||
|  |  * 02110-1301 USA | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <linux/platform_device.h> | ||||||
|  | #include <linux/slab.h> | ||||||
|  | #include <sound/core.h> | ||||||
|  | #include <sound/pcm.h> | ||||||
|  | #include <sound/soc.h> | ||||||
|  | #include <sound/soc-dapm.h> | ||||||
|  | 
 | ||||||
|  | static struct snd_soc_dai_driver dmic_dai = { | ||||||
|  | 	.name = "dmic-hifi", | ||||||
|  | 	.capture = { | ||||||
|  | 		.stream_name = "Capture", | ||||||
|  | 		.channels_min = 1, | ||||||
|  | 		.channels_max = 8, | ||||||
|  | 		.rates = SNDRV_PCM_RATE_CONTINUOUS, | ||||||
|  | 		.formats = SNDRV_PCM_FMTBIT_S32_LE | ||||||
|  | 			| SNDRV_PCM_FMTBIT_S24_LE | ||||||
|  | 			| SNDRV_PCM_FMTBIT_S16_LE, | ||||||
|  | 	}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct snd_soc_codec_driver soc_dmic = {}; | ||||||
|  | 
 | ||||||
|  | static int __devinit dmic_dev_probe(struct platform_device *pdev) | ||||||
|  | { | ||||||
|  | 	return snd_soc_register_codec(&pdev->dev, | ||||||
|  | 			&soc_dmic, &dmic_dai, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int __devexit dmic_dev_remove(struct platform_device *pdev) | ||||||
|  | { | ||||||
|  | 	snd_soc_unregister_codec(&pdev->dev); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | MODULE_ALIAS("platform:dmic-codec"); | ||||||
|  | 
 | ||||||
|  | static struct platform_driver dmic_driver = { | ||||||
|  | 	.driver = { | ||||||
|  | 		.name = "dmic-codec", | ||||||
|  | 		.owner = THIS_MODULE, | ||||||
|  | 	}, | ||||||
|  | 	.probe = dmic_dev_probe, | ||||||
|  | 	.remove = __devexit_p(dmic_dev_remove), | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static int __init dmic_init(void) | ||||||
|  | { | ||||||
|  | 	return platform_driver_register(&dmic_driver); | ||||||
|  | } | ||||||
|  | module_init(dmic_init); | ||||||
|  | 
 | ||||||
|  | static void __exit dmic_exit(void) | ||||||
|  | { | ||||||
|  | 	platform_driver_unregister(&dmic_driver); | ||||||
|  | } | ||||||
|  | module_exit(dmic_exit); | ||||||
|  | 
 | ||||||
|  | MODULE_DESCRIPTION("Generic DMIC driver"); | ||||||
|  | MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>"); | ||||||
|  | MODULE_LICENSE("GPL"); | ||||||
| @ -42,14 +42,15 @@ | |||||||
| #include <sound/tlv320dac33-plat.h> | #include <sound/tlv320dac33-plat.h> | ||||||
| #include "tlv320dac33.h" | #include "tlv320dac33.h" | ||||||
| 
 | 
 | ||||||
| #define DAC33_BUFFER_SIZE_BYTES		24576	/* bytes, 12288 16 bit words, | /*
 | ||||||
| 						 * 6144 stereo */ |  * The internal FIFO is 24576 bytes long | ||||||
| #define DAC33_BUFFER_SIZE_SAMPLES	6144 |  * It can be configured to hold 16bit or 24bit samples | ||||||
| 
 |  * In 16bit configuration the FIFO can hold 6144 stereo samples | ||||||
| #define NSAMPLE_MAX		5700 |  * In 24bit configuration the FIFO can hold 4096 stereo samples | ||||||
| 
 |  */ | ||||||
| #define MODE7_LTHR		10 | #define DAC33_FIFO_SIZE_16BIT	6144 | ||||||
| #define MODE7_UTHR		(DAC33_BUFFER_SIZE_SAMPLES - 10) | #define DAC33_FIFO_SIZE_24BIT	4096 | ||||||
|  | #define DAC33_MODE7_MARGIN	10	/* Safety margin for FIFO in Mode7 */ | ||||||
| 
 | 
 | ||||||
| #define BURST_BASEFREQ_HZ	49152000 | #define BURST_BASEFREQ_HZ	49152000 | ||||||
| 
 | 
 | ||||||
| @ -99,16 +100,11 @@ struct tlv320dac33_priv { | |||||||
| 	unsigned int refclk; | 	unsigned int refclk; | ||||||
| 
 | 
 | ||||||
| 	unsigned int alarm_threshold;	/* set to be half of LATENCY_TIME_MS */ | 	unsigned int alarm_threshold;	/* set to be half of LATENCY_TIME_MS */ | ||||||
| 	unsigned int nsample_min;	/* nsample should not be lower than
 |  | ||||||
| 					 * this */ |  | ||||||
| 	unsigned int nsample_max;	/* nsample should not be higher than
 |  | ||||||
| 					 * this */ |  | ||||||
| 	enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ | 	enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ | ||||||
|  | 	unsigned int fifo_size;		/* Size of the FIFO in samples */ | ||||||
| 	unsigned int nsample;		/* burst read amount from host */ | 	unsigned int nsample;		/* burst read amount from host */ | ||||||
| 	int mode1_latency;		/* latency caused by the i2c writes in
 | 	int mode1_latency;		/* latency caused by the i2c writes in
 | ||||||
| 					 * us */ | 					 * us */ | ||||||
| 	int auto_fifo_config; 		/* Configure the FIFO based on the
 |  | ||||||
| 					 * period size */ |  | ||||||
| 	u8 burst_bclkdiv;		/* BCLK divider value in burst mode */ | 	u8 burst_bclkdiv;		/* BCLK divider value in burst mode */ | ||||||
| 	unsigned int burst_rate;	/* Interface speed in Burst modes */ | 	unsigned int burst_rate;	/* Interface speed in Burst modes */ | ||||||
| 
 | 
 | ||||||
| @ -302,7 +298,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec) | |||||||
| 	if (unlikely(!dac33->chip_power)) | 	if (unlikely(!dac33->chip_power)) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	/* 44-46: DAC Control Registers */ |  | ||||||
| 	/* A : DAC sample rate Fsref/1.5 */ | 	/* A : DAC sample rate Fsref/1.5 */ | ||||||
| 	dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0)); | 	dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0)); | ||||||
| 	/* B : DAC src=normal, not muted */ | 	/* B : DAC src=normal, not muted */ | ||||||
| @ -325,6 +320,10 @@ static void dac33_init_chip(struct snd_soc_codec *codec) | |||||||
| 		    dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL)); | 		    dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL)); | ||||||
| 	dac33_write(codec, DAC33_LINER_TO_RLO_VOL, | 	dac33_write(codec, DAC33_LINER_TO_RLO_VOL, | ||||||
| 		    dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); | 		    dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); | ||||||
|  | 
 | ||||||
|  | 	dac33_write(codec, DAC33_OUT_AMP_CTRL, | ||||||
|  | 		    dac33_read_reg_cache(codec, DAC33_OUT_AMP_CTRL)); | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline int dac33_read_id(struct snd_soc_codec *codec) | static inline int dac33_read_id(struct snd_soc_codec *codec) | ||||||
| @ -436,73 +435,6 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w, | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int dac33_get_nsample(struct snd_kcontrol *kcontrol, |  | ||||||
| 			 struct snd_ctl_elem_value *ucontrol) |  | ||||||
| { |  | ||||||
| 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |  | ||||||
| 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |  | ||||||
| 
 |  | ||||||
| 	ucontrol->value.integer.value[0] = dac33->nsample; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int dac33_set_nsample(struct snd_kcontrol *kcontrol, |  | ||||||
| 			 struct snd_ctl_elem_value *ucontrol) |  | ||||||
| { |  | ||||||
| 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |  | ||||||
| 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |  | ||||||
| 	int ret = 0; |  | ||||||
| 
 |  | ||||||
| 	if (dac33->nsample == ucontrol->value.integer.value[0]) |  | ||||||
| 		return 0; |  | ||||||
| 
 |  | ||||||
| 	if (ucontrol->value.integer.value[0] < dac33->nsample_min || |  | ||||||
| 	    ucontrol->value.integer.value[0] > dac33->nsample_max) { |  | ||||||
| 		ret = -EINVAL; |  | ||||||
| 	} else { |  | ||||||
| 		dac33->nsample = ucontrol->value.integer.value[0]; |  | ||||||
| 		/* Re calculate the burst time */ |  | ||||||
| 		dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, |  | ||||||
| 						      dac33->nsample); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int dac33_get_uthr(struct snd_kcontrol *kcontrol, |  | ||||||
| 			 struct snd_ctl_elem_value *ucontrol) |  | ||||||
| { |  | ||||||
| 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |  | ||||||
| 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |  | ||||||
| 
 |  | ||||||
| 	ucontrol->value.integer.value[0] = dac33->uthr; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int dac33_set_uthr(struct snd_kcontrol *kcontrol, |  | ||||||
| 			 struct snd_ctl_elem_value *ucontrol) |  | ||||||
| { |  | ||||||
| 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |  | ||||||
| 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |  | ||||||
| 	int ret = 0; |  | ||||||
| 
 |  | ||||||
| 	if (dac33->substream) |  | ||||||
| 		return -EBUSY; |  | ||||||
| 
 |  | ||||||
| 	if (dac33->uthr == ucontrol->value.integer.value[0]) |  | ||||||
| 		return 0; |  | ||||||
| 
 |  | ||||||
| 	if (ucontrol->value.integer.value[0] < (MODE7_LTHR + 10) || |  | ||||||
| 	    ucontrol->value.integer.value[0] > MODE7_UTHR) |  | ||||||
| 		ret = -EINVAL; |  | ||||||
| 	else |  | ||||||
| 		dac33->uthr = ucontrol->value.integer.value[0]; |  | ||||||
| 
 |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, | static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, | ||||||
| 			 struct snd_ctl_elem_value *ucontrol) | 			 struct snd_ctl_elem_value *ucontrol) | ||||||
| { | { | ||||||
| @ -587,13 +519,6 @@ static const struct snd_kcontrol_new dac33_mode_snd_controls[] = { | |||||||
| 		 dac33_get_fifo_mode, dac33_set_fifo_mode), | 		 dac33_get_fifo_mode, dac33_set_fifo_mode), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const struct snd_kcontrol_new dac33_fifo_snd_controls[] = { |  | ||||||
| 	SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0, |  | ||||||
| 		dac33_get_nsample, dac33_set_nsample), |  | ||||||
| 	SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0, |  | ||||||
| 		 dac33_get_uthr, dac33_set_uthr), |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* Analog bypass */ | /* Analog bypass */ | ||||||
| static const struct snd_kcontrol_new dac33_dapm_abypassl_control = | static const struct snd_kcontrol_new dac33_dapm_abypassl_control = | ||||||
| 	SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1); | 	SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1); | ||||||
| @ -601,6 +526,25 @@ static const struct snd_kcontrol_new dac33_dapm_abypassl_control = | |||||||
| static const struct snd_kcontrol_new dac33_dapm_abypassr_control = | static const struct snd_kcontrol_new dac33_dapm_abypassr_control = | ||||||
| 	SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1); | 	SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1); | ||||||
| 
 | 
 | ||||||
|  | /* LOP L/R invert selection */ | ||||||
|  | static const char *dac33_lr_lom_texts[] = {"DAC", "LOP"}; | ||||||
|  | 
 | ||||||
|  | static const struct soc_enum dac33_left_lom_enum = | ||||||
|  | 	SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 3, | ||||||
|  | 			ARRAY_SIZE(dac33_lr_lom_texts), | ||||||
|  | 			dac33_lr_lom_texts); | ||||||
|  | 
 | ||||||
|  | static const struct snd_kcontrol_new dac33_dapm_left_lom_control = | ||||||
|  | SOC_DAPM_ENUM("Route", dac33_left_lom_enum); | ||||||
|  | 
 | ||||||
|  | static const struct soc_enum dac33_right_lom_enum = | ||||||
|  | 	SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 2, | ||||||
|  | 			ARRAY_SIZE(dac33_lr_lom_texts), | ||||||
|  | 			dac33_lr_lom_texts); | ||||||
|  | 
 | ||||||
|  | static const struct snd_kcontrol_new dac33_dapm_right_lom_control = | ||||||
|  | SOC_DAPM_ENUM("Route", dac33_right_lom_enum); | ||||||
|  | 
 | ||||||
| static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { | static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { | ||||||
| 	SND_SOC_DAPM_OUTPUT("LEFT_LO"), | 	SND_SOC_DAPM_OUTPUT("LEFT_LO"), | ||||||
| 	SND_SOC_DAPM_OUTPUT("RIGHT_LO"), | 	SND_SOC_DAPM_OUTPUT("RIGHT_LO"), | ||||||
| @ -617,6 +561,18 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { | |||||||
| 	SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0, | 	SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0, | ||||||
| 				&dac33_dapm_abypassr_control), | 				&dac33_dapm_abypassr_control), | ||||||
| 
 | 
 | ||||||
|  | 	SND_SOC_DAPM_MUX("Left LOM Inverted From", SND_SOC_NOPM, 0, 0, | ||||||
|  | 		&dac33_dapm_left_lom_control), | ||||||
|  | 	SND_SOC_DAPM_MUX("Right LOM Inverted From", SND_SOC_NOPM, 0, 0, | ||||||
|  | 		&dac33_dapm_right_lom_control), | ||||||
|  | 	/*
 | ||||||
|  | 	 * For DAPM path, when only the anlog bypass path is enabled, and the | ||||||
|  | 	 * LOP inverted from the corresponding DAC side. | ||||||
|  | 	 * This is needed, so we can attach the DAC power supply in this case. | ||||||
|  | 	 */ | ||||||
|  | 	SND_SOC_DAPM_PGA("Left Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||||||
|  | 	SND_SOC_DAPM_PGA("Right Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||||||
|  | 
 | ||||||
| 	SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier", | 	SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier", | ||||||
| 			 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), | 			 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), | ||||||
| 	SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier", | 	SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier", | ||||||
| @ -639,11 +595,22 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||||||
| 	{"Output Left Amplifier", NULL, "DACL"}, | 	{"Output Left Amplifier", NULL, "DACL"}, | ||||||
| 	{"Output Right Amplifier", NULL, "DACR"}, | 	{"Output Right Amplifier", NULL, "DACR"}, | ||||||
| 
 | 
 | ||||||
| 	{"Output Left Amplifier", NULL, "Analog Left Bypass"}, | 	{"Left Bypass PGA", NULL, "Analog Left Bypass"}, | ||||||
| 	{"Output Right Amplifier", NULL, "Analog Right Bypass"}, | 	{"Right Bypass PGA", NULL, "Analog Right Bypass"}, | ||||||
| 
 | 
 | ||||||
| 	{"Output Left Amplifier", NULL, "Left DAC Power"}, | 	{"Left LOM Inverted From", "DAC", "Left Bypass PGA"}, | ||||||
| 	{"Output Right Amplifier", NULL, "Right DAC Power"}, | 	{"Right LOM Inverted From", "DAC", "Right Bypass PGA"}, | ||||||
|  | 	{"Left LOM Inverted From", "LOP", "Analog Left Bypass"}, | ||||||
|  | 	{"Right LOM Inverted From", "LOP", "Analog Right Bypass"}, | ||||||
|  | 
 | ||||||
|  | 	{"Output Left Amplifier", NULL, "Left LOM Inverted From"}, | ||||||
|  | 	{"Output Right Amplifier", NULL, "Right LOM Inverted From"}, | ||||||
|  | 
 | ||||||
|  | 	{"DACL", NULL, "Left DAC Power"}, | ||||||
|  | 	{"DACR", NULL, "Right DAC Power"}, | ||||||
|  | 
 | ||||||
|  | 	{"Left Bypass PGA", NULL, "Left DAC Power"}, | ||||||
|  | 	{"Right Bypass PGA", NULL, "Right DAC Power"}, | ||||||
| 
 | 
 | ||||||
| 	/* output */ | 	/* output */ | ||||||
| 	{"LEFT_LO", NULL, "Output Left Amplifier"}, | 	{"LEFT_LO", NULL, "Output Left Amplifier"}, | ||||||
| @ -732,7 +699,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) | |||||||
| 		spin_unlock_irq(&dac33->lock); | 		spin_unlock_irq(&dac33->lock); | ||||||
| 
 | 
 | ||||||
| 		dac33_write16(codec, DAC33_PREFILL_MSB, | 		dac33_write16(codec, DAC33_PREFILL_MSB, | ||||||
| 				DAC33_THRREG(MODE7_LTHR)); | 				DAC33_THRREG(DAC33_MODE7_MARGIN)); | ||||||
| 
 | 
 | ||||||
| 		/* Enable Upper Threshold IRQ */ | 		/* Enable Upper Threshold IRQ */ | ||||||
| 		dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT); | 		dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT); | ||||||
| @ -842,6 +809,8 @@ static int dac33_startup(struct snd_pcm_substream *substream, | |||||||
| 	/* Stream started, save the substream pointer */ | 	/* Stream started, save the substream pointer */ | ||||||
| 	dac33->substream = substream; | 	dac33->substream = substream; | ||||||
| 
 | 
 | ||||||
|  | 	snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); | ||||||
|  | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -853,18 +822,17 @@ static void dac33_shutdown(struct snd_pcm_substream *substream, | |||||||
| 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | ||||||
| 
 | 
 | ||||||
| 	dac33->substream = NULL; | 	dac33->substream = NULL; | ||||||
| 
 |  | ||||||
| 	/* Reset the nSample restrictions */ |  | ||||||
| 	dac33->nsample_min = 0; |  | ||||||
| 	dac33->nsample_max = NSAMPLE_MAX; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #define CALC_BURST_RATE(bclkdiv, bclk_per_sample) \ | ||||||
|  | 	(BURST_BASEFREQ_HZ / bclkdiv / bclk_per_sample) | ||||||
| static int dac33_hw_params(struct snd_pcm_substream *substream, | static int dac33_hw_params(struct snd_pcm_substream *substream, | ||||||
| 			   struct snd_pcm_hw_params *params, | 			   struct snd_pcm_hw_params *params, | ||||||
| 			   struct snd_soc_dai *dai) | 			   struct snd_soc_dai *dai) | ||||||
| { | { | ||||||
| 	struct snd_soc_pcm_runtime *rtd = substream->private_data; | 	struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||||||
| 	struct snd_soc_codec *codec = rtd->codec; | 	struct snd_soc_codec *codec = rtd->codec; | ||||||
|  | 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | ||||||
| 
 | 
 | ||||||
| 	/* Check parameters for validity */ | 	/* Check parameters for validity */ | ||||||
| 	switch (params_rate(params)) { | 	switch (params_rate(params)) { | ||||||
| @ -879,6 +847,12 @@ static int dac33_hw_params(struct snd_pcm_substream *substream, | |||||||
| 
 | 
 | ||||||
| 	switch (params_format(params)) { | 	switch (params_format(params)) { | ||||||
| 	case SNDRV_PCM_FORMAT_S16_LE: | 	case SNDRV_PCM_FORMAT_S16_LE: | ||||||
|  | 		dac33->fifo_size = DAC33_FIFO_SIZE_16BIT; | ||||||
|  | 		dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32); | ||||||
|  | 		break; | ||||||
|  | 	case SNDRV_PCM_FORMAT_S32_LE: | ||||||
|  | 		dac33->fifo_size = DAC33_FIFO_SIZE_24BIT; | ||||||
|  | 		dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 64); | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		dev_err(codec->dev, "unsupported format %d\n", | 		dev_err(codec->dev, "unsupported format %d\n", | ||||||
| @ -933,6 +907,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) | |||||||
| 		aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16); | 		aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16); | ||||||
| 		fifoctrl_a |= DAC33_WIDTH; | 		fifoctrl_a |= DAC33_WIDTH; | ||||||
| 		break; | 		break; | ||||||
|  | 	case SNDRV_PCM_FORMAT_S32_LE: | ||||||
|  | 		aictrl_a |= (DAC33_NCYCL_32 | DAC33_WLEN_24); | ||||||
|  | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		dev_err(codec->dev, "unsupported format %d\n", | 		dev_err(codec->dev, "unsupported format %d\n", | ||||||
| 			substream->runtime->format); | 			substream->runtime->format); | ||||||
| @ -1067,7 +1044,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) | |||||||
| 		dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, | 		dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, | ||||||
| 							dac33->burst_bclkdiv); | 							dac33->burst_bclkdiv); | ||||||
| 	else | 	else | ||||||
|  | 		if (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE) | ||||||
| 			dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); | 			dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); | ||||||
|  | 		else | ||||||
|  | 			dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 16); | ||||||
| 
 | 
 | ||||||
| 	switch (dac33->fifo_mode) { | 	switch (dac33->fifo_mode) { | ||||||
| 	case DAC33_FIFO_MODE1: | 	case DAC33_FIFO_MODE1: | ||||||
| @ -1080,7 +1060,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) | |||||||
| 		 * at the bottom, and also at the top of the FIFO | 		 * at the bottom, and also at the top of the FIFO | ||||||
| 		 */ | 		 */ | ||||||
| 		dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr)); | 		dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr)); | ||||||
| 		dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR)); | 		dac33_write16(codec, DAC33_LTHR_MSB, | ||||||
|  | 			      DAC33_THRREG(DAC33_MODE7_MARGIN)); | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		break; | 		break; | ||||||
| @ -1109,10 +1090,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||||||
| 		/* Number of samples under i2c latency */ | 		/* Number of samples under i2c latency */ | ||||||
| 		dac33->alarm_threshold = US_TO_SAMPLES(rate, | 		dac33->alarm_threshold = US_TO_SAMPLES(rate, | ||||||
| 						dac33->mode1_latency); | 						dac33->mode1_latency); | ||||||
| 		nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - | 		nsample_limit = dac33->fifo_size - dac33->alarm_threshold; | ||||||
| 				dac33->alarm_threshold; |  | ||||||
| 
 | 
 | ||||||
| 		if (dac33->auto_fifo_config) { |  | ||||||
| 		if (period_size <= dac33->alarm_threshold) | 		if (period_size <= dac33->alarm_threshold) | ||||||
| 			/*
 | 			/*
 | ||||||
| 			 * Configure nSamaple to number of periods, | 			 * Configure nSamaple to number of periods, | ||||||
| @ -1126,25 +1105,6 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||||||
| 			dac33->nsample = nsample_limit; | 			dac33->nsample = nsample_limit; | ||||||
| 		else | 		else | ||||||
| 			dac33->nsample = period_size; | 			dac33->nsample = period_size; | ||||||
| 		} else { |  | ||||||
| 			/* nSample time shall not be shorter than i2c latency */ |  | ||||||
| 			dac33->nsample_min = dac33->alarm_threshold; |  | ||||||
| 			/*
 |  | ||||||
| 			 * nSample should not be bigger than alsa buffer minus |  | ||||||
| 			 * size of one period to avoid overruns |  | ||||||
| 			 */ |  | ||||||
| 			dac33->nsample_max = substream->runtime->buffer_size - |  | ||||||
| 						period_size; |  | ||||||
| 
 |  | ||||||
| 			if (dac33->nsample_max > nsample_limit) |  | ||||||
| 				dac33->nsample_max = nsample_limit; |  | ||||||
| 
 |  | ||||||
| 			/* Correct the nSample if it is outside of the ranges */ |  | ||||||
| 			if (dac33->nsample < dac33->nsample_min) |  | ||||||
| 				dac33->nsample = dac33->nsample_min; |  | ||||||
| 			if (dac33->nsample > dac33->nsample_max) |  | ||||||
| 				dac33->nsample = dac33->nsample_max; |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, | 		dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, | ||||||
| 						      dac33->nsample); | 						      dac33->nsample); | ||||||
| @ -1152,19 +1112,16 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||||||
| 		dac33->t_stamp2 = 0; | 		dac33->t_stamp2 = 0; | ||||||
| 		break; | 		break; | ||||||
| 	case DAC33_FIFO_MODE7: | 	case DAC33_FIFO_MODE7: | ||||||
| 		if (dac33->auto_fifo_config) { | 		dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate, | ||||||
| 			dac33->uthr = UTHR_FROM_PERIOD_SIZE( |  | ||||||
| 					period_size, |  | ||||||
| 					rate, |  | ||||||
| 						    dac33->burst_rate) + 9; | 						    dac33->burst_rate) + 9; | ||||||
| 			if (dac33->uthr > MODE7_UTHR) | 		if (dac33->uthr > (dac33->fifo_size - DAC33_MODE7_MARGIN)) | ||||||
| 				dac33->uthr = MODE7_UTHR; | 			dac33->uthr = dac33->fifo_size - DAC33_MODE7_MARGIN; | ||||||
| 			if (dac33->uthr < (MODE7_LTHR + 10)) | 		if (dac33->uthr < (DAC33_MODE7_MARGIN + 10)) | ||||||
| 				dac33->uthr = (MODE7_LTHR + 10); | 			dac33->uthr = (DAC33_MODE7_MARGIN + 10); | ||||||
| 		} | 
 | ||||||
| 		dac33->mode7_us_to_lthr = | 		dac33->mode7_us_to_lthr = | ||||||
| 				SAMPLES_TO_US(substream->runtime->rate, | 				SAMPLES_TO_US(substream->runtime->rate, | ||||||
| 					dac33->uthr - MODE7_LTHR + 1); | 					dac33->uthr - DAC33_MODE7_MARGIN + 1); | ||||||
| 		dac33->t_stamp1 = 0; | 		dac33->t_stamp1 = 0; | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| @ -1282,8 +1239,8 @@ static snd_pcm_sframes_t dac33_dai_delay( | |||||||
| 			samples += (samples_in - samples_out); | 			samples += (samples_in - samples_out); | ||||||
| 
 | 
 | ||||||
| 			if (likely(samples > 0)) | 			if (likely(samples > 0)) | ||||||
| 				delay = samples > DAC33_BUFFER_SIZE_SAMPLES ? | 				delay = samples > dac33->fifo_size ? | ||||||
| 					DAC33_BUFFER_SIZE_SAMPLES : samples; | 					dac33->fifo_size : samples; | ||||||
| 			else | 			else | ||||||
| 				delay = 0; | 				delay = 0; | ||||||
| 		} | 		} | ||||||
| @ -1335,7 +1292,7 @@ static snd_pcm_sframes_t dac33_dai_delay( | |||||||
| 			samples_in = US_TO_SAMPLES( | 			samples_in = US_TO_SAMPLES( | ||||||
| 					dac33->burst_rate, | 					dac33->burst_rate, | ||||||
| 					time_delta); | 					time_delta); | ||||||
| 			delay = MODE7_LTHR + samples_in - samples_out; | 			delay = DAC33_MODE7_MARGIN + samples_in - samples_out; | ||||||
| 
 | 
 | ||||||
| 			if (unlikely(delay > uthr)) | 			if (unlikely(delay > uthr)) | ||||||
| 				delay = uthr; | 				delay = uthr; | ||||||
| @ -1486,14 +1443,10 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||||||
| 	snd_soc_add_controls(codec, dac33_snd_controls, | 	snd_soc_add_controls(codec, dac33_snd_controls, | ||||||
| 			     ARRAY_SIZE(dac33_snd_controls)); | 			     ARRAY_SIZE(dac33_snd_controls)); | ||||||
| 	/* Only add the FIFO controls, if we have valid IRQ number */ | 	/* Only add the FIFO controls, if we have valid IRQ number */ | ||||||
| 	if (dac33->irq >= 0) { | 	if (dac33->irq >= 0) | ||||||
| 		snd_soc_add_controls(codec, dac33_mode_snd_controls, | 		snd_soc_add_controls(codec, dac33_mode_snd_controls, | ||||||
| 				     ARRAY_SIZE(dac33_mode_snd_controls)); | 				     ARRAY_SIZE(dac33_mode_snd_controls)); | ||||||
| 		/* FIFO usage controls only, if autoio config is not selected */ | 
 | ||||||
| 		if (!dac33->auto_fifo_config) |  | ||||||
| 			snd_soc_add_controls(codec, dac33_fifo_snd_controls, |  | ||||||
| 					ARRAY_SIZE(dac33_fifo_snd_controls)); |  | ||||||
| 	} |  | ||||||
| 	dac33_add_widgets(codec); | 	dac33_add_widgets(codec); | ||||||
| 
 | 
 | ||||||
| err_power: | err_power: | ||||||
| @ -1542,7 +1495,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { | |||||||
| 
 | 
 | ||||||
| #define DAC33_RATES	(SNDRV_PCM_RATE_44100 | \ | #define DAC33_RATES	(SNDRV_PCM_RATE_44100 | \ | ||||||
| 			 SNDRV_PCM_RATE_48000) | 			 SNDRV_PCM_RATE_48000) | ||||||
| #define DAC33_FORMATS	SNDRV_PCM_FMTBIT_S16_LE | #define DAC33_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||||||
| 
 | 
 | ||||||
| static struct snd_soc_dai_ops dac33_dai_ops = { | static struct snd_soc_dai_ops dac33_dai_ops = { | ||||||
| 	.startup	= dac33_startup, | 	.startup	= dac33_startup, | ||||||
| @ -1590,17 +1543,11 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client, | |||||||
| 
 | 
 | ||||||
| 	dac33->power_gpio = pdata->power_gpio; | 	dac33->power_gpio = pdata->power_gpio; | ||||||
| 	dac33->burst_bclkdiv = pdata->burst_bclkdiv; | 	dac33->burst_bclkdiv = pdata->burst_bclkdiv; | ||||||
| 	/* Pre calculate the burst rate */ |  | ||||||
| 	dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32; |  | ||||||
| 	dac33->keep_bclk = pdata->keep_bclk; | 	dac33->keep_bclk = pdata->keep_bclk; | ||||||
| 	dac33->auto_fifo_config = pdata->auto_fifo_config; |  | ||||||
| 	dac33->mode1_latency = pdata->mode1_latency; | 	dac33->mode1_latency = pdata->mode1_latency; | ||||||
| 	if (!dac33->mode1_latency) | 	if (!dac33->mode1_latency) | ||||||
| 		dac33->mode1_latency = 10000; /* 10ms */ | 		dac33->mode1_latency = 10000; /* 10ms */ | ||||||
| 	dac33->irq = client->irq; | 	dac33->irq = client->irq; | ||||||
| 	dac33->nsample = NSAMPLE_MAX; |  | ||||||
| 	dac33->nsample_max = NSAMPLE_MAX; |  | ||||||
| 	dac33->uthr = MODE7_UTHR; |  | ||||||
| 	/* Disable FIFO use by default */ | 	/* Disable FIFO use by default */ | ||||||
| 	dac33->fifo_mode = DAC33_FIFO_BYPASS; | 	dac33->fifo_mode = DAC33_FIFO_BYPASS; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -339,7 +339,6 @@ EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable); | |||||||
| int tpa6130a2_add_controls(struct snd_soc_codec *codec) | int tpa6130a2_add_controls(struct snd_soc_codec *codec) | ||||||
| { | { | ||||||
| 	struct	tpa6130a2_data *data; | 	struct	tpa6130a2_data *data; | ||||||
| 	struct snd_soc_dapm_context *dapm = &codec->dapm; |  | ||||||
| 
 | 
 | ||||||
| 	if (tpa6130a2_client == NULL) | 	if (tpa6130a2_client == NULL) | ||||||
| 		return -ENODEV; | 		return -ENODEV; | ||||||
|  | |||||||
| @ -1138,19 +1138,19 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||||||
| 			SND_SOC_NOPM, 0, 0, &hsr_mux_controls), | 			SND_SOC_NOPM, 0, 0, &hsr_mux_controls), | ||||||
| 
 | 
 | ||||||
| 	/* Analog playback drivers */ | 	/* Analog playback drivers */ | ||||||
| 	SND_SOC_DAPM_PGA_E("Handsfree Left Driver", | 	SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver", | ||||||
| 			TWL6040_REG_HFLCTL, 4, 0, NULL, 0, | 			TWL6040_REG_HFLCTL, 4, 0, NULL, 0, | ||||||
| 			pga_event, | 			pga_event, | ||||||
| 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||||||
| 	SND_SOC_DAPM_PGA_E("Handsfree Right Driver", | 	SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver", | ||||||
| 			TWL6040_REG_HFRCTL, 4, 0, NULL, 0, | 			TWL6040_REG_HFRCTL, 4, 0, NULL, 0, | ||||||
| 			pga_event, | 			pga_event, | ||||||
| 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||||||
| 	SND_SOC_DAPM_PGA_E("Headset Left Driver", | 	SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver", | ||||||
| 			TWL6040_REG_HSLCTL, 2, 0, NULL, 0, | 			TWL6040_REG_HSLCTL, 2, 0, NULL, 0, | ||||||
| 			pga_event, | 			pga_event, | ||||||
| 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||||||
| 	SND_SOC_DAPM_PGA_E("Headset Right Driver", | 	SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver", | ||||||
| 			TWL6040_REG_HSRCTL, 2, 0, NULL, 0, | 			TWL6040_REG_HSRCTL, 2, 0, NULL, 0, | ||||||
| 			pga_event, | 			pga_event, | ||||||
| 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "wm8995.h" | #include "wm8995.h" | ||||||
| 
 | 
 | ||||||
| static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] __devinitconst = { | static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = { | ||||||
| 	[0]     = 0x8995, [5]     = 0x0100, [16]    = 0x000b, [17]    = 0x000b, | 	[0]     = 0x8995, [5]     = 0x0100, [16]    = 0x000b, [17]    = 0x000b, | ||||||
| 	[24]    = 0x02c0, [25]    = 0x02c0, [26]    = 0x02c0, [27]    = 0x02c0, | 	[24]    = 0x02c0, [25]    = 0x02c0, [26]    = 0x02c0, [27]    = 0x02c0, | ||||||
| 	[28]    = 0x000f, [32]    = 0x0005, [33]    = 0x0005, [40]    = 0x0003, | 	[28]    = 0x000f, [32]    = 0x0005, [33]    = 0x0005, [40]    = 0x0003, | ||||||
|  | |||||||
| @ -102,6 +102,17 @@ static const int omap24xx_dma_reqs[][2] = { | |||||||
| static const int omap24xx_dma_reqs[][2] = {}; | static const int omap24xx_dma_reqs[][2] = {}; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if defined(CONFIG_ARCH_OMAP4) | ||||||
|  | static const int omap44xx_dma_reqs[][2] = { | ||||||
|  | 	{ OMAP44XX_DMA_MCBSP1_TX, OMAP44XX_DMA_MCBSP1_RX }, | ||||||
|  | 	{ OMAP44XX_DMA_MCBSP2_TX, OMAP44XX_DMA_MCBSP2_RX }, | ||||||
|  | 	{ OMAP44XX_DMA_MCBSP3_TX, OMAP44XX_DMA_MCBSP3_RX }, | ||||||
|  | 	{ OMAP44XX_DMA_MCBSP4_TX, OMAP44XX_DMA_MCBSP4_RX }, | ||||||
|  | }; | ||||||
|  | #else | ||||||
|  | static const int omap44xx_dma_reqs[][2] = {}; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if defined(CONFIG_ARCH_OMAP2420) | #if defined(CONFIG_ARCH_OMAP2420) | ||||||
| static const unsigned long omap2420_mcbsp_port[][2] = { | static const unsigned long omap2420_mcbsp_port[][2] = { | ||||||
| 	{ OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, | 	{ OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, | ||||||
| @ -147,6 +158,21 @@ static const unsigned long omap34xx_mcbsp_port[][2] = { | |||||||
| static const unsigned long omap34xx_mcbsp_port[][2] = {}; | static const unsigned long omap34xx_mcbsp_port[][2] = {}; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if defined(CONFIG_ARCH_OMAP4) | ||||||
|  | static const unsigned long omap44xx_mcbsp_port[][2] = { | ||||||
|  | 	{ OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, | ||||||
|  | 	  OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, | ||||||
|  | 	{ OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR, | ||||||
|  | 	  OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR }, | ||||||
|  | 	{ OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR, | ||||||
|  | 	  OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, | ||||||
|  | 	{ OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, | ||||||
|  | 	  OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, | ||||||
|  | }; | ||||||
|  | #else | ||||||
|  | static const unsigned long omap44xx_mcbsp_port[][2] = {}; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) | static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) | ||||||
| { | { | ||||||
| 	struct snd_soc_pcm_runtime *rtd = substream->private_data; | 	struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||||||
| @ -224,7 +250,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, | |||||||
| 	 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) | 	 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) | ||||||
| 	 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) | 	 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) | ||||||
| 	 */ | 	 */ | ||||||
| 	if (cpu_is_omap343x()) { | 	if (cpu_is_omap343x() || cpu_is_omap44xx()) { | ||||||
| 		/*
 | 		/*
 | ||||||
| 		* Rule for the buffer size. We should not allow | 		* Rule for the buffer size. We should not allow | ||||||
| 		* smaller buffer than the FIFO size to avoid underruns | 		* smaller buffer than the FIFO size to avoid underruns | ||||||
| @ -332,6 +358,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||||||
| 	} else if (cpu_is_omap343x()) { | 	} else if (cpu_is_omap343x()) { | ||||||
| 		dma = omap24xx_dma_reqs[bus_id][substream->stream]; | 		dma = omap24xx_dma_reqs[bus_id][substream->stream]; | ||||||
| 		port = omap34xx_mcbsp_port[bus_id][substream->stream]; | 		port = omap34xx_mcbsp_port[bus_id][substream->stream]; | ||||||
|  | 	 } else if (cpu_is_omap44xx()) { | ||||||
|  | 		dma = omap44xx_dma_reqs[bus_id][substream->stream]; | ||||||
|  | 		port = omap44xx_mcbsp_port[bus_id][substream->stream]; | ||||||
| 	} else { | 	} else { | ||||||
| 		return -ENODEV; | 		return -ENODEV; | ||||||
| 	} | 	} | ||||||
| @ -498,11 +527,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||||||
| 	regs->spcr2	|= XINTM(3) | FREE; | 	regs->spcr2	|= XINTM(3) | FREE; | ||||||
| 	regs->spcr1	|= RINTM(3); | 	regs->spcr1	|= RINTM(3); | ||||||
| 	/* RFIG and XFIG are not defined in 34xx */ | 	/* RFIG and XFIG are not defined in 34xx */ | ||||||
| 	if (!cpu_is_omap34xx()) { | 	if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) { | ||||||
| 		regs->rcr2	|= RFIG; | 		regs->rcr2	|= RFIG; | ||||||
| 		regs->xcr2	|= XFIG; | 		regs->xcr2	|= XFIG; | ||||||
| 	} | 	} | ||||||
| 	if (cpu_is_omap2430() || cpu_is_omap34xx()) { | 	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { | ||||||
| 		regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; | 		regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; | ||||||
| 		regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; | 		regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -50,6 +50,10 @@ enum omap_mcbsp_div { | |||||||
| #undef  NUM_LINKS | #undef  NUM_LINKS | ||||||
| #define NUM_LINKS	3 | #define NUM_LINKS	3 | ||||||
| #endif | #endif | ||||||
|  | #if defined(CONFIG_ARCH_OMAP4) | ||||||
|  | #undef  NUM_LINKS | ||||||
|  | #define NUM_LINKS	4 | ||||||
|  | #endif | ||||||
| #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | ||||||
| #undef  NUM_LINKS | #undef  NUM_LINKS | ||||||
| #define NUM_LINKS	5 | #define NUM_LINKS	5 | ||||||
|  | |||||||
| @ -235,6 +235,7 @@ static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) | |||||||
| 
 | 
 | ||||||
| 	snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 	snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||||||
| 	snd_soc_dapm_enable_pin(dapm, "Speaker"); | 	snd_soc_dapm_enable_pin(dapm, "Speaker"); | ||||||
|  | 	snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||||||
| 
 | 
 | ||||||
| 	snd_soc_dapm_sync(dapm); | 	snd_soc_dapm_sync(dapm); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,11 +8,11 @@ | |||||||
|  * published by the Free Software Foundation. |  * published by the Free Software Foundation. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <linux/clkdev.h> | ||||||
| #include <linux/device.h> | #include <linux/device.h> | ||||||
| #include <linux/firmware.h> | #include <linux/firmware.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
| 
 | 
 | ||||||
| #include <asm/clkdev.h> |  | ||||||
| #include <asm/clock.h> | #include <asm/clock.h> | ||||||
| 
 | 
 | ||||||
| #include <cpu/sh7722.h> | #include <cpu/sh7722.h> | ||||||
|  | |||||||
| @ -1339,7 +1339,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) | |||||||
| 			goto err; | 			goto err; | ||||||
| 		} | 		} | ||||||
| 		lzo_blocks[i]->sync_bmp = sync_bmp; | 		lzo_blocks[i]->sync_bmp = sync_bmp; | ||||||
| 		lzo_blocks[i]->sync_bmp_nbits = reg_size; | 		lzo_blocks[i]->sync_bmp_nbits = bmp_size; | ||||||
| 		/* alloc the working space for the compressed block */ | 		/* alloc the working space for the compressed block */ | ||||||
| 		ret = snd_soc_lzo_prepare(lzo_blocks[i]); | 		ret = snd_soc_lzo_prepare(lzo_blocks[i]); | ||||||
| 		if (ret < 0) | 		if (ret < 0) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user