Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Speyside modules for Cragganmore - board data probing
0004 //
0005 // Copyright 2011 Wolfson Microelectronics plc
0006 //  Mark Brown <broonie@opensource.wolfsonmicro.com>
0007 
0008 #include <linux/export.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/i2c.h>
0011 #include <linux/spi/spi.h>
0012 #include <linux/gpio/machine.h>
0013 
0014 #include <linux/mfd/wm831x/irq.h>
0015 #include <linux/mfd/wm831x/gpio.h>
0016 #include <linux/mfd/wm8994/pdata.h>
0017 #include <linux/mfd/arizona/pdata.h>
0018 
0019 #include <linux/regulator/machine.h>
0020 
0021 #include <sound/wm0010.h>
0022 #include <sound/wm2200.h>
0023 #include <sound/wm5100.h>
0024 #include <sound/wm8996.h>
0025 #include <sound/wm8962.h>
0026 #include <sound/wm9081.h>
0027 
0028 #include <linux/platform_data/spi-s3c64xx.h>
0029 
0030 #include "cpu.h"
0031 #include "irqs.h"
0032 
0033 #include "crag6410.h"
0034 
0035 static struct wm0010_pdata wm0010_pdata = {
0036     .gpio_reset = S3C64XX_GPN(6),
0037     .reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */
0038 };
0039 
0040 static struct spi_board_info wm1253_devs[] = {
0041     [0] = {
0042         .modalias   = "wm0010",
0043         .max_speed_hz   = 26 * 1000 * 1000,
0044         .bus_num    = 0,
0045         .chip_select    = 0,
0046         .mode       = SPI_MODE_0,
0047         .irq        = S3C_EINT(4),
0048         .platform_data = &wm0010_pdata,
0049     },
0050 };
0051 
0052 static struct spi_board_info balblair_devs[] = {
0053     [0] = {
0054         .modalias   = "wm0010",
0055         .max_speed_hz   = 26 * 1000 * 1000,
0056         .bus_num    = 0,
0057         .chip_select    = 0,
0058         .mode       = SPI_MODE_0,
0059         .irq        = S3C_EINT(4),
0060         .platform_data = &wm0010_pdata,
0061     },
0062 };
0063 
0064 static struct wm5100_pdata wm5100_pdata = {
0065     .ldo_ena = S3C64XX_GPN(7),
0066     .irq_flags = IRQF_TRIGGER_HIGH,
0067     .gpio_base = CODEC_GPIO_BASE,
0068 
0069     .in_mode = {
0070         WM5100_IN_DIFF,
0071         WM5100_IN_DIFF,
0072         WM5100_IN_DIFF,
0073         WM5100_IN_SE,
0074     },
0075 
0076     .hp_pol = CODEC_GPIO_BASE + 3,
0077     .jack_modes = {
0078         { WM5100_MICDET_MICBIAS3, 0, 0 },
0079         { WM5100_MICDET_MICBIAS2, 1, 1 },
0080     },
0081 
0082     .gpio_defaults = {
0083         0,
0084         0,
0085         0,
0086         0,
0087         0x2, /* IRQ: CMOS output */
0088         0x3, /* CLKOUT: CMOS output */
0089     },
0090 };
0091 
0092 static struct wm8996_retune_mobile_config wm8996_retune[] = {
0093     {
0094         .name = "Sub LPF",
0095         .rate = 48000,
0096         .regs = {
0097             0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
0098             0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
0099             0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
0100         },
0101     },
0102     {
0103         .name = "Sub HPF",
0104         .rate = 48000,
0105         .regs = {
0106             0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
0107             0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
0108             0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
0109         },
0110     },
0111 };
0112 
0113 static struct wm8996_pdata wm8996_pdata __initdata = {
0114     .ldo_ena = S3C64XX_GPN(7),
0115     .gpio_base = CODEC_GPIO_BASE,
0116     .micdet_def = 1,
0117     .inl_mode = WM8996_DIFFERRENTIAL_1,
0118     .inr_mode = WM8996_DIFFERRENTIAL_1,
0119 
0120     .irq_flags = IRQF_TRIGGER_RISING,
0121 
0122     .gpio_default = {
0123         0x8001, /* GPIO1 == ADCLRCLK1 */
0124         0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
0125         0x0141, /* GPIO3 == HP_SEL */
0126         0x0002, /* GPIO4 == IRQ */
0127         0x020e, /* GPIO5 == CLKOUT */
0128     },
0129 
0130     .retune_mobile_cfgs = wm8996_retune,
0131     .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
0132 };
0133 
0134 static struct wm8962_pdata wm8962_pdata __initdata = {
0135     .gpio_init = {
0136         0,
0137         WM8962_GPIO_FN_OPCLK,
0138         WM8962_GPIO_FN_DMICCLK,
0139         0,
0140         0x8000 | WM8962_GPIO_FN_DMICDAT,
0141         WM8962_GPIO_FN_IRQ,    /* Open drain mode */
0142     },
0143     .in4_dc_measure = true,
0144 };
0145 
0146 static struct wm9081_pdata wm9081_pdata __initdata = {
0147     .irq_high = false,
0148     .irq_cmos = false,
0149 };
0150 
0151 static const struct i2c_board_info wm1254_devs[] = {
0152     { I2C_BOARD_INFO("wm8996", 0x1a),
0153       .platform_data = &wm8996_pdata,
0154       .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
0155     },
0156     { I2C_BOARD_INFO("wm9081", 0x6c),
0157       .platform_data = &wm9081_pdata, },
0158 };
0159 
0160 static const struct i2c_board_info wm1255_devs[] = {
0161     { I2C_BOARD_INFO("wm5100", 0x1a),
0162       .platform_data = &wm5100_pdata,
0163       .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
0164     },
0165     { I2C_BOARD_INFO("wm9081", 0x6c),
0166       .platform_data = &wm9081_pdata, },
0167 };
0168 
0169 static const struct i2c_board_info wm1259_devs[] = {
0170     { I2C_BOARD_INFO("wm8962", 0x1a),
0171       .platform_data = &wm8962_pdata,
0172       .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
0173     },
0174 };
0175 
0176 static struct regulator_init_data wm8994_ldo1 = {
0177     .supply_regulator = "WALLVDD",
0178 };
0179 
0180 static struct regulator_init_data wm8994_ldo2 = {
0181     .supply_regulator = "WALLVDD",
0182 };
0183 
0184 static struct wm8994_pdata wm8994_pdata = {
0185     .gpio_base = CODEC_GPIO_BASE,
0186     .micb2_delay = 150,
0187     .gpio_defaults = {
0188         0x3,          /* IRQ out, active high, CMOS */
0189     },
0190     .ldo = {
0191          { .init_data = &wm8994_ldo1, },
0192          { .init_data = &wm8994_ldo2, },
0193     },
0194 };
0195 
0196 static const struct i2c_board_info wm1277_devs[] = {
0197     { I2C_BOARD_INFO("wm8958", 0x1a),  /* WM8958 is the superset */
0198       .platform_data = &wm8994_pdata,
0199       .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
0200       .dev_name = "wm8958",
0201     },
0202 };
0203 
0204 static struct gpiod_lookup_table wm8994_gpiod_table = {
0205     .dev_id = "i2c-wm8958", /* I2C device name */
0206     .table = {
0207         GPIO_LOOKUP("GPION", 6,
0208                 "wlf,ldo1ena", GPIO_ACTIVE_HIGH),
0209         GPIO_LOOKUP("GPION", 4,
0210                 "wlf,ldo2ena", GPIO_ACTIVE_HIGH),
0211         { },
0212     },
0213 };
0214 
0215 static struct arizona_pdata wm5102_reva_pdata = {
0216     .gpio_base = CODEC_GPIO_BASE,
0217     .irq_flags = IRQF_TRIGGER_HIGH,
0218     .micd_pol_gpio = CODEC_GPIO_BASE + 4,
0219     .micd_rate = 6,
0220     .gpio_defaults = {
0221         [2] = 0x10000, /* AIF3TXLRCLK */
0222         [3] = 0x4,     /* OPCLK */
0223     },
0224 };
0225 
0226 static struct spi_board_info wm5102_reva_spi_devs[] = {
0227     [0] = {
0228         .modalias   = "wm5102",
0229         .max_speed_hz   = 10 * 1000 * 1000,
0230         .bus_num    = 0,
0231         .chip_select    = 1,
0232         .mode       = SPI_MODE_0,
0233         .irq        = GLENFARCLAS_PMIC_IRQ_BASE +
0234                   WM831X_IRQ_GPIO_2,
0235         .platform_data = &wm5102_reva_pdata,
0236     },
0237 };
0238 
0239 static struct gpiod_lookup_table wm5102_reva_gpiod_table = {
0240     .dev_id = "spi0.1", /* SPI device name */
0241     .table = {
0242         GPIO_LOOKUP("GPION", 7,
0243                 "wlf,ldoena", GPIO_ACTIVE_HIGH),
0244         { },
0245     },
0246 };
0247 
0248 static struct arizona_pdata wm5102_pdata = {
0249     .gpio_base = CODEC_GPIO_BASE,
0250     .irq_flags = IRQF_TRIGGER_HIGH,
0251     .micd_pol_gpio = CODEC_GPIO_BASE + 2,
0252     .gpio_defaults = {
0253         [2] = 0x10000, /* AIF3TXLRCLK */
0254         [3] = 0x4,     /* OPCLK */
0255     },
0256 };
0257 
0258 static struct spi_board_info wm5102_spi_devs[] = {
0259     [0] = {
0260         .modalias   = "wm5102",
0261         .max_speed_hz   = 10 * 1000 * 1000,
0262         .bus_num    = 0,
0263         .chip_select    = 1,
0264         .mode       = SPI_MODE_0,
0265         .irq        = GLENFARCLAS_PMIC_IRQ_BASE +
0266                   WM831X_IRQ_GPIO_2,
0267         .platform_data = &wm5102_pdata,
0268     },
0269 };
0270 
0271 static struct gpiod_lookup_table wm5102_gpiod_table = {
0272     .dev_id = "spi0.1", /* SPI device name */
0273     .table = {
0274         GPIO_LOOKUP("GPION", 7,
0275                 "wlf,ldo1ena", GPIO_ACTIVE_HIGH),
0276         { },
0277     },
0278 };
0279 
0280 static struct spi_board_info wm5110_spi_devs[] = {
0281     [0] = {
0282         .modalias   = "wm5110",
0283         .max_speed_hz   = 10 * 1000 * 1000,
0284         .bus_num    = 0,
0285         .chip_select    = 1,
0286         .mode       = SPI_MODE_0,
0287         .irq        = GLENFARCLAS_PMIC_IRQ_BASE +
0288                   WM831X_IRQ_GPIO_2,
0289         .platform_data = &wm5102_reva_pdata,
0290     },
0291 };
0292 
0293 static const struct i2c_board_info wm6230_i2c_devs[] = {
0294     { I2C_BOARD_INFO("wm9081", 0x6c),
0295       .platform_data = &wm9081_pdata, },
0296 };
0297 
0298 static struct wm2200_pdata wm2200_pdata = {
0299     .ldo_ena = S3C64XX_GPN(7),
0300     .gpio_defaults = {
0301         [2] = 0x0005,  /* GPIO3 24.576MHz output clock */
0302     },
0303 };
0304 
0305 static const struct i2c_board_info wm2200_i2c[] = {
0306     { I2C_BOARD_INFO("wm2200", 0x3a),
0307       .platform_data = &wm2200_pdata, },
0308 };
0309 
0310 static const struct {
0311     u8 id;
0312     u8 rev;
0313     const char *name;
0314     const struct i2c_board_info *i2c_devs;
0315     int num_i2c_devs;
0316     const struct spi_board_info *spi_devs;
0317     int num_spi_devs;
0318 
0319     struct gpiod_lookup_table *gpiod_table;
0320 } gf_mods[] = {
0321     { .id = 0x01, .rev = 0xff, .name = "1250-EV1 Springbank" },
0322     { .id = 0x02, .rev = 0xff, .name = "1251-EV1 Jura" },
0323     { .id = 0x03, .rev = 0xff, .name = "1252-EV1 Glenlivet" },
0324     { .id = 0x06, .rev = 0xff, .name = "WM8997-6721-CS96-EV1 Lapraoig" },
0325     { .id = 0x07, .rev = 0xff, .name = "WM5110-6271 Deanston",
0326       .spi_devs = wm5110_spi_devs,
0327       .num_spi_devs = ARRAY_SIZE(wm5110_spi_devs) },
0328     { .id = 0x08, .rev = 0xff, .name = "WM8903-6102 Tamdhu" },
0329     { .id = 0x09, .rev = 0xff, .name = "WM1811A-6305 Adelphi" },
0330     { .id = 0x0a, .rev = 0xff, .name = "WM8996-6272 Blackadder" },
0331     { .id = 0x0b, .rev = 0xff, .name = "WM8994-6235 Benromach" },
0332     { .id = 0x11, .rev = 0xff, .name = "6249-EV2 Glenfarclas", },
0333     { .id = 0x14, .rev = 0xff, .name = "6271-EV1 Lochnagar" },
0334     { .id = 0x15, .rev = 0xff, .name = "6320-EV1 Bells",
0335       .i2c_devs = wm6230_i2c_devs,
0336       .num_i2c_devs = ARRAY_SIZE(wm6230_i2c_devs) },
0337     { .id = 0x21, .rev = 0xff, .name = "1275-EV1 Mortlach" },
0338     { .id = 0x25, .rev = 0xff, .name = "1274-EV1 Glencadam" },
0339     { .id = 0x31, .rev = 0xff, .name = "1253-EV1 Tomatin",
0340       .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
0341     { .id = 0x32, .rev = 0xff, .name = "XXXX-EV1 Caol Illa" },
0342     { .id = 0x33, .rev = 0xff, .name = "XXXX-EV1 Oban" },
0343     { .id = 0x34, .rev = 0xff, .name = "WM0010-6320-CS42 Balblair",
0344       .spi_devs = balblair_devs,
0345       .num_spi_devs = ARRAY_SIZE(balblair_devs) },
0346     { .id = 0x39, .rev = 0xff, .name = "1254-EV1 Dallas Dhu",
0347       .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
0348     { .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory",
0349       .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
0350     { .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman",
0351       .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
0352     { .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" },
0353     { .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill",
0354       .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs),
0355       .gpiod_table = &wm8994_gpiod_table },
0356     { .id = 0x3e, .rev = 0, .name = "WM5102-6271-EV1-CS127 Amrut",
0357       .spi_devs = wm5102_reva_spi_devs,
0358       .num_spi_devs = ARRAY_SIZE(wm5102_reva_spi_devs),
0359       .gpiod_table = &wm5102_reva_gpiod_table },
0360     { .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut",
0361       .spi_devs = wm5102_spi_devs,
0362       .num_spi_devs = ARRAY_SIZE(wm5102_spi_devs),
0363       .gpiod_table = &wm5102_gpiod_table },
0364     { .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1",
0365       .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) },
0366 };
0367 
0368 static int wlf_gf_module_probe(struct i2c_client *i2c)
0369 {
0370     int ret, i, j, id, rev;
0371 
0372     ret = i2c_smbus_read_byte_data(i2c, 0);
0373     if (ret < 0) {
0374         dev_err(&i2c->dev, "Failed to read ID: %d\n", ret);
0375         return ret;
0376     }
0377 
0378     id = (ret & 0xfe) >> 2;
0379     rev = ret & 0x3;
0380     for (i = 0; i < ARRAY_SIZE(gf_mods); i++)
0381         if (id == gf_mods[i].id && (gf_mods[i].rev == 0xff ||
0382                         rev == gf_mods[i].rev))
0383             break;
0384 
0385     gpiod_add_lookup_table(&wm5102_reva_gpiod_table);
0386     gpiod_add_lookup_table(&wm5102_gpiod_table);
0387     gpiod_add_lookup_table(&wm8994_gpiod_table);
0388 
0389     if (i < ARRAY_SIZE(gf_mods)) {
0390         dev_info(&i2c->dev, "%s revision %d\n",
0391              gf_mods[i].name, rev + 1);
0392 
0393         for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
0394             if (IS_ERR(i2c_new_client_device(i2c->adapter,
0395                              &(gf_mods[i].i2c_devs[j]))))
0396                 dev_err(&i2c->dev, "Failed to register\n");
0397         }
0398 
0399         spi_register_board_info(gf_mods[i].spi_devs,
0400                     gf_mods[i].num_spi_devs);
0401 
0402         if (gf_mods[i].gpiod_table)
0403             gpiod_add_lookup_table(gf_mods[i].gpiod_table);
0404     } else {
0405         dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n",
0406              id, rev + 1);
0407     }
0408 
0409     return 0;
0410 }
0411 
0412 static const struct i2c_device_id wlf_gf_module_id[] = {
0413     { "wlf-gf-module", 0 },
0414     { }
0415 };
0416 
0417 static struct i2c_driver wlf_gf_module_driver = {
0418     .driver = {
0419         .name = "wlf-gf-module"
0420     },
0421     .probe_new = wlf_gf_module_probe,
0422     .id_table = wlf_gf_module_id,
0423 };
0424 
0425 static int __init wlf_gf_module_register(void)
0426 {
0427     if (!soc_is_s3c64xx())
0428         return 0;
0429 
0430     return i2c_add_driver(&wlf_gf_module_driver);
0431 }
0432 device_initcall(wlf_gf_module_register);