Loading Documentation/devicetree/bindings/sound/uniphier,evea.txt 0 → 100644 +26 −0 Original line number Diff line number Diff line Socionext EVEA - UniPhier SoC internal codec driver Required properties: - compatible : should be "socionext,uniphier-evea". - reg : offset and length of the register set for the device. - clock-names : should include following entries: "evea", "exiv" - clocks : a list of phandle, should contain an entry for each entries in clock-names. - reset-names : should include following entries: "evea", "exiv", "adamv" - resets : a list of phandle, should contain reset entries of reset-names. - #sound-dai-cells: should be 1. Example: codec { compatible = "socionext,uniphier-evea"; reg = <0x57900000 0x1000>; clock-names = "evea", "exiv"; clocks = <&sys_clk 41>, <&sys_clk 42>; reset-names = "evea", "exiv", "adamv"; resets = <&sys_rst 41>, <&sys_rst 42>, <&adamv_rst 0>; #sound-dai-cells = <1>; }; MAINTAINERS +6 −0 Original line number Diff line number Diff line Loading @@ -12593,6 +12593,12 @@ F: include/media/soc* F: drivers/media/i2c/soc_camera/ F: drivers/media/platform/soc_camera/ SOCIONEXT UNIPHIER SOUND DRIVER M: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com> L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained F: sound/soc/uniphier/ SOEKRIS NET48XX LED SUPPORT M: Chris Boot <bootc@bootc.net> S: Maintained Loading sound/soc/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ source "sound/soc/stm/Kconfig" source "sound/soc/sunxi/Kconfig" source "sound/soc/tegra/Kconfig" source "sound/soc/txx9/Kconfig" source "sound/soc/uniphier/Kconfig" source "sound/soc/ux500/Kconfig" source "sound/soc/xtensa/Kconfig" source "sound/soc/zte/Kconfig" Loading sound/soc/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ obj-$(CONFIG_SND_SOC) += stm/ obj-$(CONFIG_SND_SOC) += sunxi/ obj-$(CONFIG_SND_SOC) += tegra/ obj-$(CONFIG_SND_SOC) += txx9/ obj-$(CONFIG_SND_SOC) += uniphier/ obj-$(CONFIG_SND_SOC) += ux500/ obj-$(CONFIG_SND_SOC) += xtensa/ obj-$(CONFIG_SND_SOC) += zte/ sound/soc/codecs/uda1380.c +24 −18 Original line number Diff line number Diff line Loading @@ -37,7 +37,8 @@ struct uda1380_priv { struct snd_soc_codec *codec; unsigned int dac_clk; struct work_struct work; void *control_data; struct i2c_client *i2c; u16 *reg_cache; }; /* Loading @@ -63,7 +64,9 @@ static unsigned long uda1380_cache_dirty; static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { u16 *cache = codec->reg_cache; struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); u16 *cache = uda1380->reg_cache; if (reg == UDA1380_RESET) return 0; if (reg >= UDA1380_CACHEREGNUM) Loading @@ -77,7 +80,8 @@ static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, u16 reg, unsigned int value) { u16 *cache = codec->reg_cache; struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); u16 *cache = uda1380->reg_cache; if (reg >= UDA1380_CACHEREGNUM) return; Loading @@ -92,6 +96,7 @@ static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); u8 data[3]; /* data is Loading @@ -111,10 +116,10 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL)) return 0; pr_debug("uda1380: hw write %x val %x\n", reg, value); if (codec->hw_write(codec->control_data, data, 3) == 3) { if (i2c_master_send(uda1380->i2c, data, 3) == 3) { unsigned int val; i2c_master_send(codec->control_data, data, 1); i2c_master_recv(codec->control_data, data, 2); i2c_master_send(uda1380->i2c, data, 1); i2c_master_recv(uda1380->i2c, data, 2); val = (data[0]<<8) | data[1]; if (val != value) { pr_debug("uda1380: READ BACK VAL %x\n", Loading @@ -130,16 +135,17 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, static void uda1380_sync_cache(struct snd_soc_codec *codec) { struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); int reg; u8 data[3]; u16 *cache = codec->reg_cache; u16 *cache = uda1380->reg_cache; /* Sync reg_cache with the hardware */ for (reg = 0; reg < UDA1380_MVOL; reg++) { data[0] = reg; data[1] = (cache[reg] & 0xff00) >> 8; data[2] = cache[reg] & 0x00ff; if (codec->hw_write(codec->control_data, data, 3) != 3) if (i2c_master_send(uda1380->i2c, data, 3) != 3) dev_err(codec->dev, "%s: write to reg 0x%x failed\n", __func__, reg); } Loading @@ -148,6 +154,7 @@ static void uda1380_sync_cache(struct snd_soc_codec *codec) static int uda1380_reset(struct snd_soc_codec *codec) { struct uda1380_platform_data *pdata = codec->dev->platform_data; struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); if (gpio_is_valid(pdata->gpio_reset)) { gpio_set_value(pdata->gpio_reset, 1); Loading @@ -160,7 +167,7 @@ static int uda1380_reset(struct snd_soc_codec *codec) data[1] = 0; data[2] = 0; if (codec->hw_write(codec->control_data, data, 3) != 3) { if (i2c_master_send(uda1380->i2c, data, 3) != 3) { dev_err(codec->dev, "%s: failed\n", __func__); return -EIO; } Loading Loading @@ -695,9 +702,6 @@ static int uda1380_probe(struct snd_soc_codec *codec) uda1380->codec = codec; codec->hw_write = (hw_write_t)i2c_master_send; codec->control_data = uda1380->control_data; if (!gpio_is_valid(pdata->gpio_power)) { ret = uda1380_reset(codec); if (ret) Loading Loading @@ -727,11 +731,6 @@ static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = { .set_bias_level = uda1380_set_bias_level, .suspend_bias_off = true, .reg_cache_size = ARRAY_SIZE(uda1380_reg), .reg_word_size = sizeof(u16), .reg_cache_default = uda1380_reg, .reg_cache_step = 1, .component_driver = { .controls = uda1380_snd_controls, .num_controls = ARRAY_SIZE(uda1380_snd_controls), Loading Loading @@ -771,8 +770,15 @@ static int uda1380_i2c_probe(struct i2c_client *i2c, return ret; } uda1380->reg_cache = devm_kmemdup(&i2c->dev, uda1380_reg, ARRAY_SIZE(uda1380_reg) * sizeof(u16), GFP_KERNEL); if (!uda1380->reg_cache) return -ENOMEM; i2c_set_clientdata(i2c, uda1380); uda1380->control_data = i2c; uda1380->i2c = i2c; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai)); Loading Loading
Documentation/devicetree/bindings/sound/uniphier,evea.txt 0 → 100644 +26 −0 Original line number Diff line number Diff line Socionext EVEA - UniPhier SoC internal codec driver Required properties: - compatible : should be "socionext,uniphier-evea". - reg : offset and length of the register set for the device. - clock-names : should include following entries: "evea", "exiv" - clocks : a list of phandle, should contain an entry for each entries in clock-names. - reset-names : should include following entries: "evea", "exiv", "adamv" - resets : a list of phandle, should contain reset entries of reset-names. - #sound-dai-cells: should be 1. Example: codec { compatible = "socionext,uniphier-evea"; reg = <0x57900000 0x1000>; clock-names = "evea", "exiv"; clocks = <&sys_clk 41>, <&sys_clk 42>; reset-names = "evea", "exiv", "adamv"; resets = <&sys_rst 41>, <&sys_rst 42>, <&adamv_rst 0>; #sound-dai-cells = <1>; };
MAINTAINERS +6 −0 Original line number Diff line number Diff line Loading @@ -12593,6 +12593,12 @@ F: include/media/soc* F: drivers/media/i2c/soc_camera/ F: drivers/media/platform/soc_camera/ SOCIONEXT UNIPHIER SOUND DRIVER M: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com> L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained F: sound/soc/uniphier/ SOEKRIS NET48XX LED SUPPORT M: Chris Boot <bootc@bootc.net> S: Maintained Loading
sound/soc/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ source "sound/soc/stm/Kconfig" source "sound/soc/sunxi/Kconfig" source "sound/soc/tegra/Kconfig" source "sound/soc/txx9/Kconfig" source "sound/soc/uniphier/Kconfig" source "sound/soc/ux500/Kconfig" source "sound/soc/xtensa/Kconfig" source "sound/soc/zte/Kconfig" Loading
sound/soc/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ obj-$(CONFIG_SND_SOC) += stm/ obj-$(CONFIG_SND_SOC) += sunxi/ obj-$(CONFIG_SND_SOC) += tegra/ obj-$(CONFIG_SND_SOC) += txx9/ obj-$(CONFIG_SND_SOC) += uniphier/ obj-$(CONFIG_SND_SOC) += ux500/ obj-$(CONFIG_SND_SOC) += xtensa/ obj-$(CONFIG_SND_SOC) += zte/
sound/soc/codecs/uda1380.c +24 −18 Original line number Diff line number Diff line Loading @@ -37,7 +37,8 @@ struct uda1380_priv { struct snd_soc_codec *codec; unsigned int dac_clk; struct work_struct work; void *control_data; struct i2c_client *i2c; u16 *reg_cache; }; /* Loading @@ -63,7 +64,9 @@ static unsigned long uda1380_cache_dirty; static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { u16 *cache = codec->reg_cache; struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); u16 *cache = uda1380->reg_cache; if (reg == UDA1380_RESET) return 0; if (reg >= UDA1380_CACHEREGNUM) Loading @@ -77,7 +80,8 @@ static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, u16 reg, unsigned int value) { u16 *cache = codec->reg_cache; struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); u16 *cache = uda1380->reg_cache; if (reg >= UDA1380_CACHEREGNUM) return; Loading @@ -92,6 +96,7 @@ static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); u8 data[3]; /* data is Loading @@ -111,10 +116,10 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL)) return 0; pr_debug("uda1380: hw write %x val %x\n", reg, value); if (codec->hw_write(codec->control_data, data, 3) == 3) { if (i2c_master_send(uda1380->i2c, data, 3) == 3) { unsigned int val; i2c_master_send(codec->control_data, data, 1); i2c_master_recv(codec->control_data, data, 2); i2c_master_send(uda1380->i2c, data, 1); i2c_master_recv(uda1380->i2c, data, 2); val = (data[0]<<8) | data[1]; if (val != value) { pr_debug("uda1380: READ BACK VAL %x\n", Loading @@ -130,16 +135,17 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, static void uda1380_sync_cache(struct snd_soc_codec *codec) { struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); int reg; u8 data[3]; u16 *cache = codec->reg_cache; u16 *cache = uda1380->reg_cache; /* Sync reg_cache with the hardware */ for (reg = 0; reg < UDA1380_MVOL; reg++) { data[0] = reg; data[1] = (cache[reg] & 0xff00) >> 8; data[2] = cache[reg] & 0x00ff; if (codec->hw_write(codec->control_data, data, 3) != 3) if (i2c_master_send(uda1380->i2c, data, 3) != 3) dev_err(codec->dev, "%s: write to reg 0x%x failed\n", __func__, reg); } Loading @@ -148,6 +154,7 @@ static void uda1380_sync_cache(struct snd_soc_codec *codec) static int uda1380_reset(struct snd_soc_codec *codec) { struct uda1380_platform_data *pdata = codec->dev->platform_data; struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); if (gpio_is_valid(pdata->gpio_reset)) { gpio_set_value(pdata->gpio_reset, 1); Loading @@ -160,7 +167,7 @@ static int uda1380_reset(struct snd_soc_codec *codec) data[1] = 0; data[2] = 0; if (codec->hw_write(codec->control_data, data, 3) != 3) { if (i2c_master_send(uda1380->i2c, data, 3) != 3) { dev_err(codec->dev, "%s: failed\n", __func__); return -EIO; } Loading Loading @@ -695,9 +702,6 @@ static int uda1380_probe(struct snd_soc_codec *codec) uda1380->codec = codec; codec->hw_write = (hw_write_t)i2c_master_send; codec->control_data = uda1380->control_data; if (!gpio_is_valid(pdata->gpio_power)) { ret = uda1380_reset(codec); if (ret) Loading Loading @@ -727,11 +731,6 @@ static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = { .set_bias_level = uda1380_set_bias_level, .suspend_bias_off = true, .reg_cache_size = ARRAY_SIZE(uda1380_reg), .reg_word_size = sizeof(u16), .reg_cache_default = uda1380_reg, .reg_cache_step = 1, .component_driver = { .controls = uda1380_snd_controls, .num_controls = ARRAY_SIZE(uda1380_snd_controls), Loading Loading @@ -771,8 +770,15 @@ static int uda1380_i2c_probe(struct i2c_client *i2c, return ret; } uda1380->reg_cache = devm_kmemdup(&i2c->dev, uda1380_reg, ARRAY_SIZE(uda1380_reg) * sizeof(u16), GFP_KERNEL); if (!uda1380->reg_cache) return -ENOMEM; i2c_set_clientdata(i2c, uda1380); uda1380->control_data = i2c; uda1380->i2c = i2c; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai)); Loading