Loading Documentation/devicetree/bindings/sound/rt5677.txt 0 → 100644 +59 −0 Original line number Diff line number Diff line RT5677 audio CODEC This device supports I2C only. Required properties: - compatible : "realtek,rt5677". - reg : The I2C address of the device. - interrupts : The CODEC's interrupt output. - gpio-controller : Indicates this device is a GPIO controller. - #gpio-cells : Should be two. The first cell is the pin number and the second cell is used to specify optional parameters (currently unused). Optional properties: - realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin. - realtek,in1-differential - realtek,in2-differential - realtek,lout1-differential - realtek,lout2-differential - realtek,lout3-differential Boolean. Indicate MIC1/2 input and LOUT1/2/3 outputs are differential, rather than single-ended. Pins on the device (for linking into audio routes): * IN1P * IN1N * IN2P * IN2N * MICBIAS1 * DMIC1 * DMIC2 * DMIC3 * DMIC4 * LOUT1 * LOUT2 * LOUT3 Example: rt5677 { compatible = "realtek,rt5677"; reg = <0x2c>; interrupt-parent = <&gpio>; interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>; gpio-controller; #gpio-cells = <2>; realtek,pow-ldo2-gpio = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; realtek,in1-differential = "true"; }; include/sound/rt5645.h +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ struct rt5645_platform_data { /* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */ unsigned int dmic2_data_pin; /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */ unsigned int hp_det_gpio; bool gpio_hp_det_active_high; }; #endif include/sound/rt5677.h +4 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,12 @@ enum rt5677_dmic2_clk { struct rt5677_platform_data { /* IN1 IN2 can optionally be differential */ /* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */ bool in1_diff; bool in2_diff; bool lout1_diff; bool lout2_diff; bool lout3_diff; /* DMIC2 clock source selection */ enum rt5677_dmic2_clk dmic2_clk_pin; }; Loading sound/soc/codecs/rt5645.c +99 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/gpio.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> Loading Loading @@ -2103,6 +2104,77 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, return 0; } static int rt5645_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); int gpio_state, jack_type = 0; unsigned int val; gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); dev_dbg(codec->dev, "gpio = %d(%d)\n", rt5645->pdata.hp_det_gpio, gpio_state); if ((rt5645->pdata.gpio_hp_det_active_high && gpio_state) || (!rt5645->pdata.gpio_hp_det_active_high && !gpio_state)) { snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias1"); snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias2"); snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); snd_soc_dapm_force_enable_pin(&codec->dapm, "Mic Det Power"); snd_soc_dapm_sync(&codec->dapm); snd_soc_write(codec, RT5645_IN1_CTRL1, 0x0006); snd_soc_write(codec, RT5645_JD_CTRL3, 0x00b0); snd_soc_update_bits(codec, RT5645_IN1_CTRL2, RT5645_CBJ_MN_JD, 0); snd_soc_update_bits(codec, RT5645_IN1_CTRL2, RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD); msleep(400); val = snd_soc_read(codec, RT5645_IN1_CTRL3) & 0x7; dev_dbg(codec->dev, "val = %d\n", val); if (val == 1 || val == 2) jack_type = SND_JACK_HEADSET; else jack_type = SND_JACK_HEADPHONE; snd_soc_dapm_disable_pin(&codec->dapm, "micbias1"); snd_soc_dapm_disable_pin(&codec->dapm, "micbias2"); snd_soc_dapm_disable_pin(&codec->dapm, "LDO2"); snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); snd_soc_dapm_sync(&codec->dapm); } snd_soc_jack_report(rt5645->jack, jack_type, SND_JACK_HEADSET); return 0; } int rt5645_set_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); rt5645->jack = jack; rt5645_jack_detect(codec, rt5645->jack); return 0; } EXPORT_SYMBOL_GPL(rt5645_set_jack_detect); static irqreturn_t rt5645_irq(int irq, void *data) { struct rt5645_priv *rt5645 = data; rt5645_jack_detect(rt5645->codec, rt5645->jack); return IRQ_HANDLED; } static int rt5645_probe(struct snd_soc_codec *codec) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); Loading Loading @@ -2250,6 +2322,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, if (rt5645 == NULL) return -ENOMEM; rt5645->i2c = i2c; i2c_set_clientdata(i2c, rt5645); if (pdata) Loading Loading @@ -2345,12 +2418,38 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, } if (rt5645->i2c->irq) { ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "rt5645", rt5645); if (ret) dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); } if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) { ret = gpio_request(rt5645->pdata.hp_det_gpio, "rt5645"); if (ret) dev_err(&i2c->dev, "Fail gpio_request hp_det_gpio\n"); ret = gpio_direction_input(rt5645->pdata.hp_det_gpio); if (ret) dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n"); } return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, rt5645_dai, ARRAY_SIZE(rt5645_dai)); } static int rt5645_i2c_remove(struct i2c_client *i2c) { struct rt5645_priv *rt5645 = i2c_get_clientdata(i2c); if (i2c->irq) free_irq(i2c->irq, rt5645); if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) gpio_free(rt5645->pdata.hp_det_gpio); snd_soc_unregister_codec(&i2c->dev); return 0; Loading sound/soc/codecs/rt5645.h +5 −0 Original line number Diff line number Diff line Loading @@ -2166,6 +2166,8 @@ struct rt5645_priv { struct snd_soc_codec *codec; struct rt5645_platform_data pdata; struct regmap *regmap; struct i2c_client *i2c; struct snd_soc_jack *jack; int sysclk; int sysclk_src; Loading @@ -2178,4 +2180,7 @@ struct rt5645_priv { int pll_out; }; int rt5645_set_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); #endif /* __RT5645_H__ */ Loading
Documentation/devicetree/bindings/sound/rt5677.txt 0 → 100644 +59 −0 Original line number Diff line number Diff line RT5677 audio CODEC This device supports I2C only. Required properties: - compatible : "realtek,rt5677". - reg : The I2C address of the device. - interrupts : The CODEC's interrupt output. - gpio-controller : Indicates this device is a GPIO controller. - #gpio-cells : Should be two. The first cell is the pin number and the second cell is used to specify optional parameters (currently unused). Optional properties: - realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin. - realtek,in1-differential - realtek,in2-differential - realtek,lout1-differential - realtek,lout2-differential - realtek,lout3-differential Boolean. Indicate MIC1/2 input and LOUT1/2/3 outputs are differential, rather than single-ended. Pins on the device (for linking into audio routes): * IN1P * IN1N * IN2P * IN2N * MICBIAS1 * DMIC1 * DMIC2 * DMIC3 * DMIC4 * LOUT1 * LOUT2 * LOUT3 Example: rt5677 { compatible = "realtek,rt5677"; reg = <0x2c>; interrupt-parent = <&gpio>; interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>; gpio-controller; #gpio-cells = <2>; realtek,pow-ldo2-gpio = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; realtek,in1-differential = "true"; };
include/sound/rt5645.h +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ struct rt5645_platform_data { /* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */ unsigned int dmic2_data_pin; /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */ unsigned int hp_det_gpio; bool gpio_hp_det_active_high; }; #endif
include/sound/rt5677.h +4 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,12 @@ enum rt5677_dmic2_clk { struct rt5677_platform_data { /* IN1 IN2 can optionally be differential */ /* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */ bool in1_diff; bool in2_diff; bool lout1_diff; bool lout2_diff; bool lout3_diff; /* DMIC2 clock source selection */ enum rt5677_dmic2_clk dmic2_clk_pin; }; Loading
sound/soc/codecs/rt5645.c +99 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/gpio.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> Loading Loading @@ -2103,6 +2104,77 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, return 0; } static int rt5645_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); int gpio_state, jack_type = 0; unsigned int val; gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); dev_dbg(codec->dev, "gpio = %d(%d)\n", rt5645->pdata.hp_det_gpio, gpio_state); if ((rt5645->pdata.gpio_hp_det_active_high && gpio_state) || (!rt5645->pdata.gpio_hp_det_active_high && !gpio_state)) { snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias1"); snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias2"); snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); snd_soc_dapm_force_enable_pin(&codec->dapm, "Mic Det Power"); snd_soc_dapm_sync(&codec->dapm); snd_soc_write(codec, RT5645_IN1_CTRL1, 0x0006); snd_soc_write(codec, RT5645_JD_CTRL3, 0x00b0); snd_soc_update_bits(codec, RT5645_IN1_CTRL2, RT5645_CBJ_MN_JD, 0); snd_soc_update_bits(codec, RT5645_IN1_CTRL2, RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD); msleep(400); val = snd_soc_read(codec, RT5645_IN1_CTRL3) & 0x7; dev_dbg(codec->dev, "val = %d\n", val); if (val == 1 || val == 2) jack_type = SND_JACK_HEADSET; else jack_type = SND_JACK_HEADPHONE; snd_soc_dapm_disable_pin(&codec->dapm, "micbias1"); snd_soc_dapm_disable_pin(&codec->dapm, "micbias2"); snd_soc_dapm_disable_pin(&codec->dapm, "LDO2"); snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); snd_soc_dapm_sync(&codec->dapm); } snd_soc_jack_report(rt5645->jack, jack_type, SND_JACK_HEADSET); return 0; } int rt5645_set_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); rt5645->jack = jack; rt5645_jack_detect(codec, rt5645->jack); return 0; } EXPORT_SYMBOL_GPL(rt5645_set_jack_detect); static irqreturn_t rt5645_irq(int irq, void *data) { struct rt5645_priv *rt5645 = data; rt5645_jack_detect(rt5645->codec, rt5645->jack); return IRQ_HANDLED; } static int rt5645_probe(struct snd_soc_codec *codec) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); Loading Loading @@ -2250,6 +2322,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, if (rt5645 == NULL) return -ENOMEM; rt5645->i2c = i2c; i2c_set_clientdata(i2c, rt5645); if (pdata) Loading Loading @@ -2345,12 +2418,38 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, } if (rt5645->i2c->irq) { ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "rt5645", rt5645); if (ret) dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); } if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) { ret = gpio_request(rt5645->pdata.hp_det_gpio, "rt5645"); if (ret) dev_err(&i2c->dev, "Fail gpio_request hp_det_gpio\n"); ret = gpio_direction_input(rt5645->pdata.hp_det_gpio); if (ret) dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n"); } return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, rt5645_dai, ARRAY_SIZE(rt5645_dai)); } static int rt5645_i2c_remove(struct i2c_client *i2c) { struct rt5645_priv *rt5645 = i2c_get_clientdata(i2c); if (i2c->irq) free_irq(i2c->irq, rt5645); if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) gpio_free(rt5645->pdata.hp_det_gpio); snd_soc_unregister_codec(&i2c->dev); return 0; Loading
sound/soc/codecs/rt5645.h +5 −0 Original line number Diff line number Diff line Loading @@ -2166,6 +2166,8 @@ struct rt5645_priv { struct snd_soc_codec *codec; struct rt5645_platform_data pdata; struct regmap *regmap; struct i2c_client *i2c; struct snd_soc_jack *jack; int sysclk; int sysclk_src; Loading @@ -2178,4 +2180,7 @@ struct rt5645_priv { int pll_out; }; int rt5645_set_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); #endif /* __RT5645_H__ */