brcm2708: update linux 4.4 patches to latest version
[oweals/openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0430-Added-HiFiBerry-Digi-Pro-driver.patch
1 From 1a770fa3b51e674ba573628b1ad08153d9dbc39b Mon Sep 17 00:00:00 2001
2 From: "Daniel Matuschek (HiFiBerry)" <daniel@hifiberry.com>
3 Date: Tue, 26 Jul 2016 19:16:25 +0200
4 Subject: [PATCH] Added HiFiBerry Digi+ Pro driver
5
6 Signed-off-by: Daniel Matuschek <daniel@hifiberry.com>
7 ---
8  arch/arm/boot/dts/overlays/Makefile                |  1 +
9  arch/arm/boot/dts/overlays/README                  |  8 +++-
10  .../dts/overlays/hifiberry-digi-pro-overlay.dts    | 41 +++++++++++++++++
11  sound/soc/bcm/hifiberry_digi.c                     | 51 ++++++++++++++++++++++
12  4 files changed, 100 insertions(+), 1 deletion(-)
13  create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
14
15 --- a/arch/arm/boot/dts/overlays/Makefile
16 +++ b/arch/arm/boot/dts/overlays/Makefile
17 @@ -31,6 +31,7 @@ dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp
18  dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo
19  dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo
20  dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo
21 +dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi-pro.dtbo
22  dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo
23  dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo
24  dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo
25 --- a/arch/arm/boot/dts/overlays/README
26 +++ b/arch/arm/boot/dts/overlays/README
27 @@ -377,11 +377,17 @@ Params: 24db_digital_gain       Allow ga
28  
29  
30  Name:   hifiberry-digi
31 -Info:   Configures the HifiBerry Digi audio card
32 +Info:   Configures the HifiBerry Digi and Digi+ audio card
33  Load:   dtoverlay=hifiberry-digi
34  Params: <None>
35  
36  
37 +Name:   hifiberry-digi-pro
38 +Info:   Configures the HifiBerry Digi+ Pro audio card
39 +Load:   dtoverlay=hifiberry-digi-pro
40 +Params: <None>
41 +
42 +
43  Name:   hy28a
44  Info:   HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics
45          Default values match Texy's display shield
46 --- /dev/null
47 +++ b/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
48 @@ -0,0 +1,41 @@
49 +// Definitions for HiFiBerry Digi Pro
50 +/dts-v1/;
51 +/plugin/;
52 +
53 +/ {
54 +       compatible = "brcm,bcm2708";
55 +
56 +       fragment@0 {
57 +               target = <&i2s>;
58 +               __overlay__ {
59 +                       status = "okay";
60 +               };
61 +       };
62 +
63 +       fragment@1 {
64 +               target = <&i2c1>;
65 +               __overlay__ {
66 +                       #address-cells = <1>;
67 +                       #size-cells = <0>;
68 +                       status = "okay";
69 +
70 +                       wm8804@3b {
71 +                               #sound-dai-cells = <0>;
72 +                               compatible = "wlf,wm8804";
73 +                               reg = <0x3b>;
74 +                               status = "okay";
75 +                       };
76 +               };
77 +       };
78 +
79 +       fragment@2 {
80 +               target = <&sound>;
81 +               __overlay__ {
82 +                       compatible = "hifiberry,hifiberry-digi";
83 +                       i2s-controller = <&i2s>;
84 +                       status = "okay";
85 +                       clock44-gpio = <&gpio 5 0>;
86 +                       clock48-gpio = <&gpio 6 0>;
87 +               };
88 +       };
89 +};
90 --- a/sound/soc/bcm/hifiberry_digi.c
91 +++ b/sound/soc/bcm/hifiberry_digi.c
92 @@ -23,6 +23,7 @@
93  #include <sound/pcm_params.h>
94  #include <sound/soc.h>
95  #include <sound/jack.h>
96 +#include <linux/gpio/consumer.h>
97  
98  #include "../codecs/wm8804.h"
99  
100 @@ -30,9 +31,34 @@ static short int auto_shutdown_output =
101  module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
102  MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped");
103  
104 +#define CLK_44EN_RATE 22579200UL
105 +#define CLK_48EN_RATE 24576000UL
106 +
107 +static bool snd_rpi_hifiberry_is_digipro;
108 +static struct gpio_desc *snd_rpi_hifiberry_clk44gpio;
109 +static struct gpio_desc *snd_rpi_hifiberry_clk48gpio;
110  
111  static int samplerate=44100;
112  
113 +static uint32_t snd_rpi_hifiberry_digi_enable_clock(int sample_rate)
114 +{
115 +       switch (sample_rate) {
116 +       case 11025:
117 +       case 22050:
118 +       case 44100:
119 +       case 88200:
120 +       case 176400:
121 +               gpiod_set_value_cansleep(snd_rpi_hifiberry_clk44gpio, 1);
122 +               gpiod_set_value_cansleep(snd_rpi_hifiberry_clk48gpio, 0);
123 +               return CLK_44EN_RATE;
124 +       default:
125 +               gpiod_set_value_cansleep(snd_rpi_hifiberry_clk48gpio, 1);
126 +               gpiod_set_value_cansleep(snd_rpi_hifiberry_clk44gpio, 0);
127 +               return CLK_48EN_RATE;
128 +       }
129 +}
130 +
131 +
132  static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd)
133  {
134         struct snd_soc_codec *codec = rtd->codec;
135 @@ -40,6 +66,14 @@ static int snd_rpi_hifiberry_digi_init(s
136         /* enable TX output */
137         snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
138  
139 +       /* Initialize Digi+ Pro hardware */
140 +       if (snd_rpi_hifiberry_is_digipro) {
141 +               struct snd_soc_dai_link *dai = rtd->dai_link;
142 +
143 +               dai->name = "HiFiBerry Digi+ Pro";
144 +               dai->stream_name = "HiFiBerry Digi+ Pro HiFi";
145 +       }
146 +
147         return 0;
148  }
149  
150 @@ -87,6 +121,9 @@ static int snd_rpi_hifiberry_digi_hw_par
151                 mclk_freq=samplerate*128;
152                 mclk_div=WM8804_MCLKDIV_128FS;
153         }
154 +
155 +       if (snd_rpi_hifiberry_is_digipro)
156 +               sysclk = snd_rpi_hifiberry_digi_enable_clock(samplerate);
157         
158         switch (samplerate) {
159                 case 32000:
160 @@ -121,6 +158,7 @@ static int snd_rpi_hifiberry_digi_hw_par
161  
162         ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL,
163                                         sysclk, SND_SOC_CLOCK_OUT);
164 +
165         if (ret < 0) {
166                 dev_err(codec->dev,
167                 "Failed to set WM8804 SYSCLK: %d\n", ret);
168 @@ -187,6 +225,19 @@ static int snd_rpi_hifiberry_digi_probe(
169                 dai->platform_name = NULL;
170                 dai->platform_of_node = i2s_node;
171             }
172 +
173 +           snd_rpi_hifiberry_is_digipro = 1;
174 +
175 +           snd_rpi_hifiberry_clk44gpio =
176 +               devm_gpiod_get(&pdev->dev, "clock44", GPIOD_OUT_LOW);
177 +           if (IS_ERR(snd_rpi_hifiberry_clk44gpio))
178 +               snd_rpi_hifiberry_is_digipro = 0;
179 +
180 +           snd_rpi_hifiberry_clk48gpio =
181 +               devm_gpiod_get(&pdev->dev, "clock48", GPIOD_OUT_LOW);
182 +           if (IS_ERR(snd_rpi_hifiberry_clk48gpio))
183 +               snd_rpi_hifiberry_is_digipro = 0;
184 +
185         }
186  
187         ret = snd_soc_register_card(&snd_rpi_hifiberry_digi);