diff options
-rw-r--r-- | sound/soc/codecs/wm8962.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm8978.c | 2 | ||||
-rw-r--r-- | sound/soc/s3c24xx/s3c64xx-i2s.h | 1 | ||||
-rw-r--r-- | sound/soc/sh/fsi.c | 281 | ||||
-rw-r--r-- | sound/soc/sh/migor.c | 2 | ||||
-rw-r--r-- | sound/soc/soc-cache.c | 5 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 5 |
7 files changed, 144 insertions, 154 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 30984dd15c48..7de519479801 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -1744,8 +1744,6 @@ static int wm8962_probe(struct snd_soc_codec *codec) wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; - snd_soc_add_controls(codec, wm8962_snd_controls, - ARRAY_SIZE(wm8962_snd_controls)); wm8962_add_widgets(codec); wm8962_init_beep(codec); diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 676a4306cc87..13b979a71a7c 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -1038,7 +1038,7 @@ MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id); static struct i2c_driver wm8978_i2c_driver = { .driver = { - .name = "WM8978-codec", + .name = "wm8978", .owner = THIS_MODULE, }, .probe = wm8978_i2c_probe, diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h index 19bd444bf8a6..de4075d26f0c 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.h +++ b/sound/soc/s3c24xx/s3c64xx-i2s.h @@ -36,5 +36,6 @@ struct clk; (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE) +struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai); #endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 363b37a603cb..82c6190b46f3 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -102,6 +102,15 @@ #define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) /* + * FSI driver use below type name for variable + * + * xxx_len : data length + * xxx_width : data width + * xxx_offset : data offset + * xxx_num : number of data + */ + +/* * struct */ @@ -110,13 +119,13 @@ struct fsi_priv { struct snd_pcm_substream *substream; struct fsi_master *master; - int fifo_max; - int chan; + int fifo_max_num; + int chan_num; - int byte_offset; + int buff_offset; + int buff_len; int period_len; - int buffer_len; - int periods; + int period_num; u32 mst_ctrl; }; @@ -320,32 +329,43 @@ static void fsi_stream_push(struct fsi_priv *fsi, u32 period_len) { fsi->substream = substream; - fsi->buffer_len = buffer_len; + fsi->buff_len = buffer_len; + fsi->buff_offset = 0; fsi->period_len = period_len; - fsi->byte_offset = 0; - fsi->periods = 0; + fsi->period_num = 0; } static void fsi_stream_pop(struct fsi_priv *fsi) { fsi->substream = NULL; - fsi->buffer_len = 0; + fsi->buff_len = 0; + fsi->buff_offset = 0; fsi->period_len = 0; - fsi->byte_offset = 0; - fsi->periods = 0; + fsi->period_num = 0; } -static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play) +static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) { u32 status; u32 reg = is_play ? DOFF_ST : DIFF_ST; - int residue; + int data_num; status = fsi_reg_read(fsi, reg); - residue = 0x1ff & (status >> 8); - residue *= fsi->chan; + data_num = 0x1ff & (status >> 8); + data_num *= fsi->chan_num; + + return data_num; +} - return residue; +static int fsi_len2num(int len, int width) +{ + return len / width; +} + +#define fsi_num2offset(a, b) fsi_num2len(a, b) +static int fsi_num2len(int num, int width) +{ + return num * width; } /* @@ -354,50 +374,50 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play) static u8 *fsi_dma_get_area(struct fsi_priv *fsi) { - return fsi->substream->runtime->dma_area + fsi->byte_offset; + return fsi->substream->runtime->dma_area + fsi->buff_offset; } -static void fsi_dma_soft_push16(struct fsi_priv *fsi, int size) +static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num) { u16 *start; int i; start = (u16 *)fsi_dma_get_area(fsi); - for (i = 0; i < size; i++) + for (i = 0; i < num; i++) fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8)); } -static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int size) +static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int num) { u16 *start; int i; start = (u16 *)fsi_dma_get_area(fsi); - for (i = 0; i < size; i++) + for (i = 0; i < num; i++) *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8); } -static void fsi_dma_soft_push32(struct fsi_priv *fsi, int size) +static void fsi_dma_soft_push32(struct fsi_priv *fsi, int num) { u32 *start; int i; start = (u32 *)fsi_dma_get_area(fsi); - for (i = 0; i < size; i++) + for (i = 0; i < num; i++) fsi_reg_write(fsi, DODT, *(start + i)); } -static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int size) +static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int num) { u32 *start; int i; start = (u32 *)fsi_dma_get_area(fsi); - for (i = 0; i < size; i++) + for (i = 0; i < num; i++) *(start + i) = fsi_reg_read(fsi, DIDT); } @@ -492,8 +512,8 @@ static void fsi_fifo_init(struct fsi_priv *fsi, shift = fsi_master_read(master, FIFO_SZ); shift >>= fsi_is_port_a(fsi) ? AO_SZ_SHIFT : BO_SZ_SHIFT; shift &= OUT_SZ_MASK; - fsi->fifo_max = 256 << shift; - dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max); + fsi->fifo_max_num = 256 << shift; + dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max_num); /* * The maximum number of sample data varies depending @@ -514,9 +534,10 @@ static void fsi_fifo_init(struct fsi_priv *fsi, * 7 channels: 32 ( 32 x 7 = 224) * 8 channels: 32 ( 32 x 8 = 256) */ - for (i = 1; i < fsi->chan; i <<= 1) - fsi->fifo_max >>= 1; - dev_dbg(dai->dev, "%d channel %d store\n", fsi->chan, fsi->fifo_max); + for (i = 1; i < fsi->chan_num; i <<= 1) + fsi->fifo_max_num >>= 1; + dev_dbg(dai->dev, "%d channel %d store\n", + fsi->chan_num, fsi->fifo_max_num); ctrl = is_play ? DOFF_CTL : DIFF_CTL; @@ -539,16 +560,18 @@ static void fsi_soft_all_reset(struct fsi_master *master) mdelay(10); } -/* playback interrupt */ -static int fsi_data_push(struct fsi_priv *fsi, int startup) +static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int is_play) { struct snd_pcm_runtime *runtime; struct snd_pcm_substream *substream = NULL; u32 status; - int send; - int fifo_free; - int width; + u32 status_reg = is_play ? DOFF_ST : DIFF_ST; + int data_residue_num; + int data_num; + int data_num_max; + int ch_width; int over_period; + void (*fn)(struct fsi_priv *fsi, int size); if (!fsi || !fsi->substream || @@ -562,43 +585,76 @@ static int fsi_data_push(struct fsi_priv *fsi, int startup) /* FSI FIFO has limit. * So, this driver can not send periods data at a time */ - if (fsi->byte_offset >= - fsi->period_len * (fsi->periods + 1)) { + if (fsi->buff_offset >= + fsi_num2offset(fsi->period_num + 1, fsi->period_len)) { over_period = 1; - fsi->periods = (fsi->periods + 1) % runtime->periods; + fsi->period_num = (fsi->period_num + 1) % runtime->periods; - if (0 == fsi->periods) - fsi->byte_offset = 0; + if (0 == fsi->period_num) + fsi->buff_offset = 0; } /* get 1 channel data width */ - width = frames_to_bytes(runtime, 1) / fsi->chan; - - /* get send size for alsa */ - send = (fsi->buffer_len - fsi->byte_offset) / width; - - /* get FIFO free size */ - fifo_free = (fsi->fifo_max * fsi->chan) - fsi_get_fifo_residue(fsi, 1); + ch_width = frames_to_bytes(runtime, 1) / fsi->chan_num; + + /* get residue data number of alsa */ + data_residue_num = fsi_len2num(fsi->buff_len - fsi->buff_offset, + ch_width); + + if (is_play) { + /* + * for play-back + * + * data_num_max : number of FSI fifo free space + * data_num : number of ALSA residue data + */ + data_num_max = fsi->fifo_max_num * fsi->chan_num; + data_num_max -= fsi_get_fifo_data_num(fsi, is_play); + + data_num = data_residue_num; + + switch (ch_width) { + case 2: + fn = fsi_dma_soft_push16; + break; + case 4: + fn = fsi_dma_soft_push32; + break; + default: + return -EINVAL; + } + } else { + /* + * for capture + * + * data_num_max : number of ALSA free space + * data_num : number of data in FSI fifo + */ + data_num_max = data_residue_num; + data_num = fsi_get_fifo_data_num(fsi, is_play); + + switch (ch_width) { + case 2: + fn = fsi_dma_soft_pop16; + break; + case 4: + fn = fsi_dma_soft_pop32; + break; + default: + return -EINVAL; + } + } - /* size check */ - if (fifo_free < send) - send = fifo_free; + data_num = min(data_num, data_num_max); - switch (width) { - case 2: - fsi_dma_soft_push16(fsi, send); - break; - case 4: - fsi_dma_soft_push32(fsi, send); - break; - default: - return -EINVAL; - } + fn(fsi, data_num); - fsi->byte_offset += send * width; + /* update buff_offset */ + fsi->buff_offset += fsi_num2offset(data_num, ch_width); - status = fsi_reg_read(fsi, DOFF_ST); + /* check fifo status */ + status = fsi_reg_read(fsi, status_reg); if (!startup) { struct snd_soc_dai *dai = fsi_get_dai(substream); @@ -607,9 +663,10 @@ static int fsi_data_push(struct fsi_priv *fsi, int startup) if (status & ERR_UNDER) dev_err(dai->dev, "under run\n"); } - fsi_reg_write(fsi, DOFF_ST, 0); + fsi_reg_write(fsi, status_reg, 0); - fsi_irq_enable(fsi, 1); + /* re-enable irq */ + fsi_irq_enable(fsi, is_play); if (over_period) snd_pcm_period_elapsed(substream); @@ -619,78 +676,12 @@ static int fsi_data_push(struct fsi_priv *fsi, int startup) static int fsi_data_pop(struct fsi_priv *fsi, int startup) { - struct snd_pcm_runtime *runtime; - struct snd_pcm_substream *substream = NULL; - u32 status; - int free; - int fifo_fill; - int width; - int over_period; - - if (!fsi || - !fsi->substream || - !fsi->substream->runtime) - return -EINVAL; - - over_period = 0; - substream = fsi->substream; - runtime = substream->runtime; - - /* FSI FIFO has limit. - * So, this driver can not send periods data at a time - */ - if (fsi->byte_offset >= - fsi->period_len * (fsi->periods + 1)) { - - over_period = 1; - fsi->periods = (fsi->periods + 1) % runtime->periods; - - if (0 == fsi->periods) - fsi->byte_offset = 0; - } - - /* get 1 channel data width */ - width = frames_to_bytes(runtime, 1) / fsi->chan; - - /* get free space for alsa */ - free = (fsi->buffer_len - fsi->byte_offset) / width; - - /* get recv size */ - fifo_fill = fsi_get_fifo_residue(fsi, 0); - - if (free < fifo_fill) - fifo_fill = free; - - switch (width) { - case 2: - fsi_dma_soft_pop16(fsi, fifo_fill); - break; - case 4: - fsi_dma_soft_pop32(fsi, fifo_fill); - break; - default: - return -EINVAL; - } - - fsi->byte_offset += fifo_fill * width; - - status = fsi_reg_read(fsi, DIFF_ST); - if (!startup) { - struct snd_soc_dai *dai = fsi_get_dai(substream); - - if (status & ERR_OVER) - dev_err(dai->dev, "over run\n"); - if (status & ERR_UNDER) - dev_err(dai->dev, "under run\n"); - } - fsi_reg_write(fsi, DIFF_ST, 0); - - fsi_irq_enable(fsi, 0); - - if (over_period) - snd_pcm_period_elapsed(substream); + return fsi_fifo_data_ctrl(fsi, startup, 0); +} - return 0; +static int fsi_data_push(struct fsi_priv *fsi, int startup) +{ + return fsi_fifo_data_ctrl(fsi, startup, 1); } static irqreturn_t fsi_interrupt(int irq, void *data) @@ -763,29 +754,29 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, switch (fmt) { case SH_FSI_FMT_MONO: data = CR_MONO; - fsi->chan = 1; + fsi->chan_num = 1; break; case SH_FSI_FMT_MONO_DELAY: data = CR_MONO_D; - fsi->chan = 1; + fsi->chan_num = 1; break; case SH_FSI_FMT_PCM: data = CR_PCM; - fsi->chan = 2; + fsi->chan_num = 2; break; case SH_FSI_FMT_I2S: data = CR_I2S; - fsi->chan = 2; + fsi->chan_num = 2; break; case SH_FSI_FMT_TDM: - fsi->chan = is_play ? + fsi->chan_num = is_play ? SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); - data = CR_TDM | (fsi->chan - 1); + data = CR_TDM | (fsi->chan_num - 1); break; case SH_FSI_FMT_TDM_DELAY: - fsi->chan = is_play ? + fsi->chan_num = is_play ? SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); - data = CR_TDM_D | (fsi->chan - 1); + data = CR_TDM_D | (fsi->chan_num - 1); break; case SH_FSI_FMT_SPDIF: if (master->core->ver < 2) { @@ -793,7 +784,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, return -EINVAL; } data = CR_SPDIF; - fsi->chan = 2; + fsi->chan_num = 2; fsi_spdif_clk_ctrl(fsi, 1); fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010); break; @@ -992,7 +983,7 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) struct fsi_priv *fsi = fsi_get_priv(substream); long location; - location = (fsi->byte_offset - 1); + location = (fsi->buff_offset - 1); if (location < 0) location = 0; diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index f4620176a3ff..ac6c49ce6fdf 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -156,7 +156,7 @@ static struct snd_soc_dai_link migor_dai = { .cpu_dai_name = "siu-i2s-dai", .codec_dai_name = "wm8978-hifi", .platform_name = "siu-pcm-audio", - .codec_name = "wm8978-codec.0-001a", + .codec_name = "wm8978.0-001a", .ops = &migor_dai_ops, .init = migor_dai_init, }; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 12281111f100..28bf1ff980ce 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -203,8 +203,9 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, data[1] = (value >> 8) & 0xff; data[2] = value & 0xff; - if (!snd_soc_codec_volatile_register(codec, reg)) - reg_cache[reg] = value; + if (!snd_soc_codec_volatile_register(codec, reg) + && reg < codec->driver->reg_cache_size) + reg_cache[reg] = value; if (codec->cache_only) { codec->cache_sync = 1; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 6001b7f0a138..e9968ffecd1c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1451,7 +1451,6 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) snd_soc_dapm_sync(codec); /* register the rtd device */ - rtd->dev.init_name = rtd->dai_link->stream_name; rtd->dev.release = rtd_release; rtd->dev.init_name = dai_link->name; ret = device_register(&rtd->dev); @@ -1982,8 +1981,8 @@ int snd_soc_add_controls(struct snd_soc_codec *codec, const struct snd_kcontrol_new *control = &controls[i]; err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); if (err < 0) { - dev_err(codec->dev, "%s: Failed to add %s\n", - codec->name, control->name); + dev_err(codec->dev, "%s: Failed to add %s: %d\n", + codec->name, control->name, err); return err; } } |