Commit e7198134 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'topic/asoc' into for-linus

parents 26037980 bda7d2a8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ static struct snd_platform_data da830_evm_snd_data = {
	.num_serializer = ARRAY_SIZE(da830_iis_serializer_direction),
	.tdm_slots      = 2,
	.serial_dir     = da830_iis_serializer_direction,
	.eventq_no      = EVENTQ_0,
	.asp_chan_q     = EVENTQ_0,
	.version	= MCASP_VERSION_2,
	.txnumevt	= 1,
	.rxnumevt	= 1,
+1 −1
Original line number Diff line number Diff line
@@ -343,7 +343,7 @@ static struct snd_platform_data da850_evm_snd_data = {
	.num_serializer	= ARRAY_SIZE(da850_iis_serializer_direction),
	.tdm_slots	= 2,
	.serial_dir	= da850_iis_serializer_direction,
	.eventq_no	= EVENTQ_1,
	.asp_chan_q	= EVENTQ_1,
	.version	= MCASP_VERSION_2,
	.txnumevt	= 1,
	.rxnumevt	= 1,
+2 −2
Original line number Diff line number Diff line
@@ -323,7 +323,7 @@ static struct snd_platform_data dm646x_evm_snd_data[] = {
		.num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction),
		.tdm_slots      = 2,
		.serial_dir     = dm646x_iis_serializer_direction,
		.eventq_no      = EVENTQ_0,
		.asp_chan_q     = EVENTQ_0,
	},
	{
		.tx_dma_offset  = 0x400,
@@ -332,7 +332,7 @@ static struct snd_platform_data dm646x_evm_snd_data[] = {
		.num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction),
		.tdm_slots      = 32,
		.serial_dir     = dm646x_dit_serializer_direction,
		.eventq_no      = EVENTQ_0,
		.asp_chan_q     = EVENTQ_0,
	},
};

+50 −1
Original line number Diff line number Diff line
@@ -52,7 +52,8 @@
struct snd_platform_data {
	u32 tx_dma_offset;
	u32 rx_dma_offset;
	enum dma_event_q eventq_no;	/* event queue number */
	enum dma_event_q asp_chan_q;	/* event queue number for ASP channel */
	enum dma_event_q ram_chan_q;	/* event queue number for RAM channel */
	unsigned int codec_fmt;
	/*
	 * Allowing this is more efficient and eliminates left and right swaps
@@ -63,6 +64,49 @@ struct snd_platform_data {
	unsigned sram_size_playback;
	unsigned sram_size_capture;

	/*
	 * If McBSP peripheral gets the clock from an external pin,
	 * there are three chooses, that are MCBSP_CLKX, MCBSP_CLKR
	 * and MCBSP_CLKS.
	 * Depending on different hardware connections it is possible
	 * to use this setting to change the behaviour of McBSP
	 * driver. The dm365_clk_input_pin enum is available for dm365
	 */
	int clk_input_pin;

	/*
	 * This flag works when both clock and FS are outputs for the cpu
	 * and makes clock more accurate (FS is not symmetrical and the
	 * clock is very fast.
	 * The clock becoming faster is named
	 * i2s continuous serial clock (I2S_SCK) and it is an externally
	 * visible bit clock.
	 *
	 * first line : WordSelect
	 * second line : ContinuousSerialClock
	 * third line: SerialData
	 *
	 * SYMMETRICAL APPROACH:
	 *   _______________________          LEFT
	 * _|         RIGHT         |______________________|
	 *     _   _         _   _   _   _         _   _
	 *   _| |_| |_ x16 _| |_| |_| |_| |_ x16 _| |_| |_
	 *     _   _         _   _   _   _         _   _
	 *   _/ \_/ \_ ... _/ \_/ \_/ \_/ \_ ... _/ \_/ \_
	 *    \_/ \_/       \_/ \_/ \_/ \_/       \_/ \_/
	 *
	 * ACCURATE CLOCK APPROACH:
	 *   ______________          LEFT
	 * _|     RIGHT    |_______________________________|
	 *     _         _   _         _   _   _   _   _   _
	 *   _| |_ x16 _| |_| |_ x16 _| |_| |_| |_| |_| |_| |
	 *     _         _   _          _      dummy cycles
	 *   _/ \_ ... _/ \_/ \_  ... _/ \__________________
	 *    \_/       \_/ \_/        \_/
	 *
	 */
	bool i2s_accurate_sck;

	/* McASP specific fields */
	int tdm_slots;
	u8 op_mode;
@@ -78,6 +122,11 @@ enum {
	MCASP_VERSION_2,	/* DA8xx/OMAPL1x */
};

enum dm365_clk_input_pin {
	MCBSP_CLKR = 0,		/* DM365 */
	MCBSP_CLKS,
};

#define INACTIVE_MODE	0
#define TX_MODE		1
#define RX_MODE		2
+66 −1
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@ static unsigned long get_uart_rate(struct clk *clk);

static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
static int set_div_rate(struct clk *clk, unsigned long rate);

static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);

static struct clk clk_xtali = {
	.rate		= EP93XX_EXT_CLK_RATE,
@@ -112,6 +113,29 @@ static struct clk clk_video = {
	.set_rate	= set_div_rate,
};

static struct clk clk_i2s_mclk = {
	.sw_locked	= 1,
	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
	.enable_mask	= EP93XX_SYSCON_CLKDIV_ENABLE,
	.set_rate	= set_div_rate,
};

static struct clk clk_i2s_sclk = {
	.sw_locked	= 1,
	.parent		= &clk_i2s_mclk,
	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
	.enable_mask	= EP93XX_SYSCON_I2SCLKDIV_SENA,
	.set_rate	= set_i2s_sclk_rate,
};

static struct clk clk_i2s_lrclk = {
	.sw_locked	= 1,
	.parent		= &clk_i2s_sclk,
	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
	.enable_mask	= EP93XX_SYSCON_I2SCLKDIV_SENA,
	.set_rate	= set_i2s_lrclk_rate,
};

/* DMA Clocks */
static struct clk clk_m2p0 = {
	.parent		= &clk_h,
@@ -191,6 +215,9 @@ static struct clk_lookup clocks[] = {
	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
	INIT_CK("ep93xx-fb",		NULL,		&clk_video),
	INIT_CK("ep93xx-spi.0",		NULL,		&clk_spi),
	INIT_CK("ep93xx-i2s",		"mclk",		&clk_i2s_mclk),
	INIT_CK("ep93xx-i2s",		"sclk",		&clk_i2s_sclk),
	INIT_CK("ep93xx-i2s",		"lrclk",	&clk_i2s_lrclk),
	INIT_CK(NULL,			"pwm_clk",	&clk_pwm),
	INIT_CK(NULL,			"m2p0",		&clk_m2p0),
	INIT_CK(NULL,			"m2p1",		&clk_m2p1),
@@ -401,6 +428,44 @@ static int set_div_rate(struct clk *clk, unsigned long rate)
	return 0;
}

static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
{
	unsigned val = __raw_readl(clk->enable_reg);

	if (rate == clk_i2s_mclk.rate / 2)
		ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV, 
					     clk->enable_reg);
	else if (rate == clk_i2s_mclk.rate / 4)
		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV, 
					     clk->enable_reg);
	else
		return -EINVAL;

	clk_i2s_sclk.rate = rate;
	return 0;
}

static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
{
	unsigned val = __raw_readl(clk->enable_reg) & 
		~EP93XX_I2SCLKDIV_LRDIV_MASK;
	
	if (rate == clk_i2s_sclk.rate / 32)
		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
					     clk->enable_reg);
	else if (rate == clk_i2s_sclk.rate / 64)
		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
					     clk->enable_reg);
	else if (rate == clk_i2s_sclk.rate / 128)
		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
					     clk->enable_reg);
	else
		return -EINVAL;

	clk_i2s_lrclk.rate = rate;
	return 0;
}

int clk_set_rate(struct clk *clk, unsigned long rate)
{
	if (clk->set_rate)
Loading