1 // SPDX-License-Identifier: GPL-2.0
3 // Speyside modules for Cragganmore - board data probing
5 // Copyright 2011 Wolfson Microelectronics plc
6 // Mark Brown <broonie@opensource.wolfsonmicro.com>
8 #include <linux/export.h>
9 #include <linux/interrupt.h>
10 #include <linux/i2c.h>
11 #include <linux/spi/spi.h>
12 #include <linux/gpio/machine.h>
14 #include <linux/mfd/wm831x/irq.h>
15 #include <linux/mfd/wm831x/gpio.h>
16 #include <linux/mfd/wm8994/pdata.h>
17 #include <linux/mfd/arizona/pdata.h>
19 #include <linux/regulator/machine.h>
21 #include <sound/wm0010.h>
22 #include <sound/wm2200.h>
23 #include <sound/wm5100.h>
24 #include <sound/wm8996.h>
25 #include <sound/wm8962.h>
26 #include <sound/wm9081.h>
28 #include <linux/platform_data/spi-s3c64xx.h>
35 static struct gpiod_lookup_table wm0010_gpiod_table
= {
36 .dev_id
= "spi0.0", /* SPI device name */
38 /* Active high for Glenfarclas Rev 2 */
39 GPIO_LOOKUP("GPION", 6,
40 "reset", GPIO_ACTIVE_HIGH
),
45 static struct wm0010_pdata wm0010_pdata
= {
46 /* Intentionally left blank */
49 static struct spi_board_info wm1253_devs
[] = {
52 .max_speed_hz
= 26 * 1000 * 1000,
57 .platform_data
= &wm0010_pdata
,
61 static struct spi_board_info balblair_devs
[] = {
64 .max_speed_hz
= 26 * 1000 * 1000,
69 .platform_data
= &wm0010_pdata
,
73 static struct gpiod_lookup_table wm5100_gpiod_table
= {
74 .dev_id
= "1-001a", /* Device 001a on I2C bus 1 */
76 GPIO_LOOKUP("GPION", 7,
77 "wlf,ldo1ena", GPIO_ACTIVE_HIGH
),
78 GPIO_LOOKUP("wm5100", 3,
79 "hp-pol", GPIO_ACTIVE_HIGH
),
84 static struct wm5100_pdata wm5100_pdata
= {
85 .irq_flags
= IRQF_TRIGGER_HIGH
,
95 { WM5100_MICDET_MICBIAS3
, 0, 0 },
96 { WM5100_MICDET_MICBIAS2
, 1, 1 },
104 0x2, /* IRQ: CMOS output */
105 0x3, /* CLKOUT: CMOS output */
109 static struct wm8996_retune_mobile_config wm8996_retune
[] = {
114 0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
115 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
116 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
123 0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
124 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
125 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
130 static struct gpiod_lookup_table wm8996_gpiod_table
= {
131 .dev_id
= "1-001a", /* Device 001a on I2C bus 1 */
133 GPIO_LOOKUP("GPION", 7,
134 "wlf,ldo1ena", GPIO_ACTIVE_HIGH
),
139 static struct wm8996_pdata wm8996_pdata __initdata
= {
141 .inl_mode
= WM8996_DIFFERRENTIAL_1
,
142 .inr_mode
= WM8996_DIFFERRENTIAL_1
,
144 .irq_flags
= IRQF_TRIGGER_RISING
,
147 0x8001, /* GPIO1 == ADCLRCLK1 */
148 0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
149 0x0141, /* GPIO3 == HP_SEL */
150 0x0002, /* GPIO4 == IRQ */
151 0x020e, /* GPIO5 == CLKOUT */
154 .retune_mobile_cfgs
= wm8996_retune
,
155 .num_retune_mobile_cfgs
= ARRAY_SIZE(wm8996_retune
),
158 static struct wm8962_pdata wm8962_pdata __initdata
= {
161 WM8962_GPIO_FN_OPCLK
,
162 WM8962_GPIO_FN_DMICCLK
,
164 0x8000 | WM8962_GPIO_FN_DMICDAT
,
165 WM8962_GPIO_FN_IRQ
, /* Open drain mode */
167 .in4_dc_measure
= true,
170 static struct wm9081_pdata wm9081_pdata __initdata
= {
175 static const struct i2c_board_info wm1254_devs
[] = {
176 { I2C_BOARD_INFO("wm8996", 0x1a),
177 .platform_data
= &wm8996_pdata
,
178 .irq
= GLENFARCLAS_PMIC_IRQ_BASE
+ WM831X_IRQ_GPIO_2
,
180 { I2C_BOARD_INFO("wm9081", 0x6c),
181 .platform_data
= &wm9081_pdata
, },
184 static const struct i2c_board_info wm1255_devs
[] = {
185 { I2C_BOARD_INFO("wm5100", 0x1a),
186 .platform_data
= &wm5100_pdata
,
187 .irq
= GLENFARCLAS_PMIC_IRQ_BASE
+ WM831X_IRQ_GPIO_2
,
189 { I2C_BOARD_INFO("wm9081", 0x6c),
190 .platform_data
= &wm9081_pdata
, },
193 static const struct i2c_board_info wm1259_devs
[] = {
194 { I2C_BOARD_INFO("wm8962", 0x1a),
195 .platform_data
= &wm8962_pdata
,
196 .irq
= GLENFARCLAS_PMIC_IRQ_BASE
+ WM831X_IRQ_GPIO_2
,
200 static struct regulator_init_data wm8994_ldo1
= {
201 .supply_regulator
= "WALLVDD",
204 static struct regulator_init_data wm8994_ldo2
= {
205 .supply_regulator
= "WALLVDD",
208 static struct wm8994_pdata wm8994_pdata
= {
209 .gpio_base
= CODEC_GPIO_BASE
,
212 0x3, /* IRQ out, active high, CMOS */
215 { .init_data
= &wm8994_ldo1
, },
216 { .init_data
= &wm8994_ldo2
, },
220 static const struct i2c_board_info wm1277_devs
[] = {
221 { I2C_BOARD_INFO("wm8958", 0x1a), /* WM8958 is the superset */
222 .platform_data
= &wm8994_pdata
,
223 .irq
= GLENFARCLAS_PMIC_IRQ_BASE
+ WM831X_IRQ_GPIO_2
,
224 .dev_name
= "wm8958",
228 static struct gpiod_lookup_table wm8994_gpiod_table
= {
229 .dev_id
= "i2c-wm8958", /* I2C device name */
231 GPIO_LOOKUP("GPION", 6,
232 "wlf,ldo1ena", GPIO_ACTIVE_HIGH
),
233 GPIO_LOOKUP("GPION", 4,
234 "wlf,ldo2ena", GPIO_ACTIVE_HIGH
),
239 static struct arizona_pdata wm5102_reva_pdata
= {
240 .gpio_base
= CODEC_GPIO_BASE
,
241 .irq_flags
= IRQF_TRIGGER_HIGH
,
242 .micd_pol_gpio
= CODEC_GPIO_BASE
+ 4,
245 [2] = 0x10000, /* AIF3TXLRCLK */
246 [3] = 0x4, /* OPCLK */
250 static struct spi_board_info wm5102_reva_spi_devs
[] = {
252 .modalias
= "wm5102",
253 .max_speed_hz
= 10 * 1000 * 1000,
257 .irq
= GLENFARCLAS_PMIC_IRQ_BASE
+
259 .platform_data
= &wm5102_reva_pdata
,
263 static struct gpiod_lookup_table wm5102_reva_gpiod_table
= {
264 .dev_id
= "spi0.1", /* SPI device name */
266 GPIO_LOOKUP("GPION", 7,
267 "wlf,ldoena", GPIO_ACTIVE_HIGH
),
272 static struct arizona_pdata wm5102_pdata
= {
273 .gpio_base
= CODEC_GPIO_BASE
,
274 .irq_flags
= IRQF_TRIGGER_HIGH
,
275 .micd_pol_gpio
= CODEC_GPIO_BASE
+ 2,
277 [2] = 0x10000, /* AIF3TXLRCLK */
278 [3] = 0x4, /* OPCLK */
282 static struct spi_board_info wm5102_spi_devs
[] = {
284 .modalias
= "wm5102",
285 .max_speed_hz
= 10 * 1000 * 1000,
289 .irq
= GLENFARCLAS_PMIC_IRQ_BASE
+
291 .platform_data
= &wm5102_pdata
,
295 static struct gpiod_lookup_table wm5102_gpiod_table
= {
296 .dev_id
= "spi0.1", /* SPI device name */
298 GPIO_LOOKUP("GPION", 7,
299 "wlf,ldo1ena", GPIO_ACTIVE_HIGH
),
304 static struct spi_board_info wm5110_spi_devs
[] = {
306 .modalias
= "wm5110",
307 .max_speed_hz
= 10 * 1000 * 1000,
311 .irq
= GLENFARCLAS_PMIC_IRQ_BASE
+
313 .platform_data
= &wm5102_reva_pdata
,
317 static const struct i2c_board_info wm6230_i2c_devs
[] = {
318 { I2C_BOARD_INFO("wm9081", 0x6c),
319 .platform_data
= &wm9081_pdata
, },
322 static struct wm2200_pdata wm2200_pdata
= {
324 [2] = 0x0005, /* GPIO3 24.576MHz output clock */
328 static struct gpiod_lookup_table wm2200_gpiod_table
= {
329 .dev_id
= "1-003a", /* Device 003a on I2C bus 1 */
331 GPIO_LOOKUP("GPION", 7,
332 "wlf,ldo1ena", GPIO_ACTIVE_HIGH
),
337 static const struct i2c_board_info wm2200_i2c
[] = {
338 { I2C_BOARD_INFO("wm2200", 0x3a),
339 .platform_data
= &wm2200_pdata
, },
342 static const struct {
346 const struct i2c_board_info
*i2c_devs
;
348 const struct spi_board_info
*spi_devs
;
351 struct gpiod_lookup_table
*gpiod_table
;
353 { .id
= 0x01, .rev
= 0xff, .name
= "1250-EV1 Springbank" },
354 { .id
= 0x02, .rev
= 0xff, .name
= "1251-EV1 Jura" },
355 { .id
= 0x03, .rev
= 0xff, .name
= "1252-EV1 Glenlivet" },
356 { .id
= 0x06, .rev
= 0xff, .name
= "WM8997-6721-CS96-EV1 Lapraoig" },
357 { .id
= 0x07, .rev
= 0xff, .name
= "WM5110-6271 Deanston",
358 .spi_devs
= wm5110_spi_devs
,
359 .num_spi_devs
= ARRAY_SIZE(wm5110_spi_devs
) },
360 { .id
= 0x08, .rev
= 0xff, .name
= "WM8903-6102 Tamdhu" },
361 { .id
= 0x09, .rev
= 0xff, .name
= "WM1811A-6305 Adelphi" },
362 { .id
= 0x0a, .rev
= 0xff, .name
= "WM8996-6272 Blackadder" },
363 { .id
= 0x0b, .rev
= 0xff, .name
= "WM8994-6235 Benromach" },
364 { .id
= 0x11, .rev
= 0xff, .name
= "6249-EV2 Glenfarclas", },
365 { .id
= 0x14, .rev
= 0xff, .name
= "6271-EV1 Lochnagar" },
366 { .id
= 0x15, .rev
= 0xff, .name
= "6320-EV1 Bells",
367 .i2c_devs
= wm6230_i2c_devs
,
368 .num_i2c_devs
= ARRAY_SIZE(wm6230_i2c_devs
) },
369 { .id
= 0x21, .rev
= 0xff, .name
= "1275-EV1 Mortlach" },
370 { .id
= 0x25, .rev
= 0xff, .name
= "1274-EV1 Glencadam" },
371 { .id
= 0x31, .rev
= 0xff, .name
= "1253-EV1 Tomatin",
372 .spi_devs
= wm1253_devs
, .num_spi_devs
= ARRAY_SIZE(wm1253_devs
),
373 .gpiod_table
= &wm0010_gpiod_table
},
374 { .id
= 0x32, .rev
= 0xff, .name
= "XXXX-EV1 Caol Illa" },
375 { .id
= 0x33, .rev
= 0xff, .name
= "XXXX-EV1 Oban" },
376 { .id
= 0x34, .rev
= 0xff, .name
= "WM0010-6320-CS42 Balblair",
377 .spi_devs
= balblair_devs
,
378 .num_spi_devs
= ARRAY_SIZE(balblair_devs
) },
379 { .id
= 0x39, .rev
= 0xff, .name
= "1254-EV1 Dallas Dhu",
380 .i2c_devs
= wm1254_devs
, .num_i2c_devs
= ARRAY_SIZE(wm1254_devs
),
381 .gpiod_table
= &wm8996_gpiod_table
},
382 { .id
= 0x3a, .rev
= 0xff, .name
= "1259-EV1 Tobermory",
383 .i2c_devs
= wm1259_devs
, .num_i2c_devs
= ARRAY_SIZE(wm1259_devs
) },
384 { .id
= 0x3b, .rev
= 0xff, .name
= "1255-EV1 Kilchoman",
385 .i2c_devs
= wm1255_devs
, .num_i2c_devs
= ARRAY_SIZE(wm1255_devs
),
386 .gpiod_table
= &wm5100_gpiod_table
},
387 { .id
= 0x3c, .rev
= 0xff, .name
= "1273-EV1 Longmorn" },
388 { .id
= 0x3d, .rev
= 0xff, .name
= "1277-EV1 Littlemill",
389 .i2c_devs
= wm1277_devs
, .num_i2c_devs
= ARRAY_SIZE(wm1277_devs
),
390 .gpiod_table
= &wm8994_gpiod_table
},
391 { .id
= 0x3e, .rev
= 0, .name
= "WM5102-6271-EV1-CS127 Amrut",
392 .spi_devs
= wm5102_reva_spi_devs
,
393 .num_spi_devs
= ARRAY_SIZE(wm5102_reva_spi_devs
),
394 .gpiod_table
= &wm5102_reva_gpiod_table
},
395 { .id
= 0x3e, .rev
= -1, .name
= "WM5102-6271-EV1-CS127 Amrut",
396 .spi_devs
= wm5102_spi_devs
,
397 .num_spi_devs
= ARRAY_SIZE(wm5102_spi_devs
),
398 .gpiod_table
= &wm5102_gpiod_table
},
399 { .id
= 0x3f, .rev
= -1, .name
= "WM2200-6271-CS90-M-REV1",
400 .i2c_devs
= wm2200_i2c
, .num_i2c_devs
= ARRAY_SIZE(wm2200_i2c
),
401 .gpiod_table
= &wm2200_gpiod_table
},
404 static int wlf_gf_module_probe(struct i2c_client
*i2c
)
406 int ret
, i
, j
, id
, rev
;
408 ret
= i2c_smbus_read_byte_data(i2c
, 0);
410 dev_err(&i2c
->dev
, "Failed to read ID: %d\n", ret
);
414 id
= (ret
& 0xfe) >> 2;
416 for (i
= 0; i
< ARRAY_SIZE(gf_mods
); i
++)
417 if (id
== gf_mods
[i
].id
&& (gf_mods
[i
].rev
== 0xff ||
418 rev
== gf_mods
[i
].rev
))
421 gpiod_add_lookup_table(&wm5102_reva_gpiod_table
);
422 gpiod_add_lookup_table(&wm5102_gpiod_table
);
423 gpiod_add_lookup_table(&wm8994_gpiod_table
);
425 if (i
< ARRAY_SIZE(gf_mods
)) {
426 dev_info(&i2c
->dev
, "%s revision %d\n",
427 gf_mods
[i
].name
, rev
+ 1);
429 for (j
= 0; j
< gf_mods
[i
].num_i2c_devs
; j
++) {
430 if (IS_ERR(i2c_new_client_device(i2c
->adapter
,
431 &(gf_mods
[i
].i2c_devs
[j
]))))
432 dev_err(&i2c
->dev
, "Failed to register\n");
435 spi_register_board_info(gf_mods
[i
].spi_devs
,
436 gf_mods
[i
].num_spi_devs
);
438 if (gf_mods
[i
].gpiod_table
)
439 gpiod_add_lookup_table(gf_mods
[i
].gpiod_table
);
441 dev_warn(&i2c
->dev
, "Unknown module ID 0x%x revision %d\n",
448 static const struct i2c_device_id wlf_gf_module_id
[] = {
453 static struct i2c_driver wlf_gf_module_driver
= {
455 .name
= "wlf-gf-module"
457 .probe
= wlf_gf_module_probe
,
458 .id_table
= wlf_gf_module_id
,
461 static int __init
wlf_gf_module_register(void)
463 if (!soc_is_s3c64xx())
466 return i2c_add_driver(&wlf_gf_module_driver
);
468 device_initcall(wlf_gf_module_register
);