0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/acpi.h>
0011 #include <linux/err.h>
0012 #include <linux/gpio/consumer.h>
0013 #include <linux/gpio/machine.h>
0014 #include <linux/module.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/regmap.h>
0017 #include <linux/regulator/consumer.h>
0018 #include <linux/slab.h>
0019 #include <linux/spi/spi.h>
0020 #include <linux/of.h>
0021 #include <uapi/linux/input-event-codes.h>
0022
0023 #include <linux/mfd/arizona/core.h>
0024
0025 #include "arizona.h"
0026
0027 #ifdef CONFIG_ACPI
0028 static const struct acpi_gpio_params reset_gpios = { 1, 0, false };
0029 static const struct acpi_gpio_params ldoena_gpios = { 2, 0, false };
0030
0031 static const struct acpi_gpio_mapping arizona_acpi_gpios[] = {
0032 { "reset-gpios", &reset_gpios, 1, },
0033 { "wlf,ldoena-gpios", &ldoena_gpios, 1 },
0034 { }
0035 };
0036
0037
0038
0039
0040
0041 static const struct gpiod_lookup arizona_soc_gpios[] = {
0042 { "arizona", 2, "wlf,spkvdd-ena", 0, GPIO_ACTIVE_HIGH },
0043 { "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW },
0044 };
0045
0046 static void arizona_spi_acpi_remove_lookup(void *lookup)
0047 {
0048 gpiod_remove_lookup_table(lookup);
0049 }
0050
0051
0052 static int arizona_spi_acpi_windows_probe(struct arizona *arizona)
0053 {
0054 struct gpiod_lookup_table *lookup;
0055 acpi_status status;
0056 int ret;
0057
0058
0059 devm_acpi_dev_add_driver_gpios(arizona->dev, arizona_acpi_gpios);
0060
0061
0062 lookup = devm_kzalloc(arizona->dev,
0063 struct_size(lookup, table, ARRAY_SIZE(arizona_soc_gpios) + 1),
0064 GFP_KERNEL);
0065 if (!lookup)
0066 return -ENOMEM;
0067
0068 lookup->dev_id = dev_name(arizona->dev);
0069 memcpy(lookup->table, arizona_soc_gpios, sizeof(arizona_soc_gpios));
0070
0071 gpiod_add_lookup_table(lookup);
0072 ret = devm_add_action_or_reset(arizona->dev, arizona_spi_acpi_remove_lookup, lookup);
0073 if (ret)
0074 return ret;
0075
0076
0077 status = acpi_evaluate_object(ACPI_HANDLE(arizona->dev), "CLKE", NULL, NULL);
0078 if (ACPI_FAILURE(status))
0079 dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status);
0080
0081 return 0;
0082 }
0083
0084
0085 static int arizona_spi_acpi_android_probe(struct arizona *arizona)
0086 {
0087 int ret;
0088
0089
0090
0091
0092
0093
0094 arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset", GPIOD_OUT_LOW);
0095 if (IS_ERR(arizona->pdata.reset)) {
0096 ret = PTR_ERR(arizona->pdata.reset);
0097 if (ret == -ENOENT) {
0098 dev_info_once(arizona->dev,
0099 "Deferring probe till GPIO lookup is registered\n");
0100 ret = -EPROBE_DEFER;
0101 }
0102 return dev_err_probe(arizona->dev, ret, "getting reset GPIO\n");
0103 }
0104
0105 return 0;
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
0121 { .max = 11, .key = KEY_PLAYPAUSE },
0122 { .max = 186, .key = KEY_VOICECOMMAND },
0123 { .max = 348, .key = KEY_VOLUMEUP },
0124 { .max = 752, .key = KEY_VOLUMEDOWN },
0125 };
0126
0127 static int arizona_spi_acpi_probe(struct arizona *arizona)
0128 {
0129 struct acpi_device *adev = ACPI_COMPANION(arizona->dev);
0130 int ret;
0131
0132 if (acpi_dev_hid_uid_match(adev, "10WM5102", NULL))
0133 ret = arizona_spi_acpi_android_probe(arizona);
0134 else
0135 ret = arizona_spi_acpi_windows_probe(arizona);
0136
0137 if (ret)
0138 return ret;
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 arizona->pdata.irq_flags = IRQF_TRIGGER_LOW;
0154
0155
0156 arizona->pdata.micd_detect_debounce = 200;
0157
0158
0159 arizona->pdata.micd_ranges = arizona_micd_aosp_ranges;
0160 arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges);
0161
0162 return 0;
0163 }
0164
0165 static const struct acpi_device_id arizona_acpi_match[] = {
0166 {
0167 .id = "WM510204",
0168 .driver_data = WM5102,
0169 },
0170 {
0171 .id = "WM510205",
0172 .driver_data = WM5102,
0173 },
0174 {
0175 .id = "10WM5102",
0176 .driver_data = WM5102,
0177 },
0178 { }
0179 };
0180 MODULE_DEVICE_TABLE(acpi, arizona_acpi_match);
0181 #else
0182 static int arizona_spi_acpi_probe(struct arizona *arizona)
0183 {
0184 return -ENODEV;
0185 }
0186 #endif
0187
0188 static int arizona_spi_probe(struct spi_device *spi)
0189 {
0190 const struct spi_device_id *id = spi_get_device_id(spi);
0191 const void *match_data;
0192 struct arizona *arizona;
0193 const struct regmap_config *regmap_config = NULL;
0194 unsigned long type = 0;
0195 int ret;
0196
0197 match_data = device_get_match_data(&spi->dev);
0198 if (match_data)
0199 type = (unsigned long)match_data;
0200 else if (id)
0201 type = id->driver_data;
0202
0203 switch (type) {
0204 case WM5102:
0205 if (IS_ENABLED(CONFIG_MFD_WM5102))
0206 regmap_config = &wm5102_spi_regmap;
0207 break;
0208 case WM5110:
0209 case WM8280:
0210 if (IS_ENABLED(CONFIG_MFD_WM5110))
0211 regmap_config = &wm5110_spi_regmap;
0212 break;
0213 case WM1831:
0214 case CS47L24:
0215 if (IS_ENABLED(CONFIG_MFD_CS47L24))
0216 regmap_config = &cs47l24_spi_regmap;
0217 break;
0218 default:
0219 dev_err(&spi->dev, "Unknown device type %ld\n", type);
0220 return -EINVAL;
0221 }
0222
0223 if (!regmap_config) {
0224 dev_err(&spi->dev,
0225 "No kernel support for device type %ld\n", type);
0226 return -EINVAL;
0227 }
0228
0229 arizona = devm_kzalloc(&spi->dev, sizeof(*arizona), GFP_KERNEL);
0230 if (arizona == NULL)
0231 return -ENOMEM;
0232
0233 arizona->regmap = devm_regmap_init_spi(spi, regmap_config);
0234 if (IS_ERR(arizona->regmap)) {
0235 ret = PTR_ERR(arizona->regmap);
0236 dev_err(&spi->dev, "Failed to allocate register map: %d\n",
0237 ret);
0238 return ret;
0239 }
0240
0241 arizona->type = type;
0242 arizona->dev = &spi->dev;
0243 arizona->irq = spi->irq;
0244
0245 if (has_acpi_companion(&spi->dev)) {
0246 ret = arizona_spi_acpi_probe(arizona);
0247 if (ret)
0248 return ret;
0249 }
0250
0251 return arizona_dev_init(arizona);
0252 }
0253
0254 static void arizona_spi_remove(struct spi_device *spi)
0255 {
0256 struct arizona *arizona = spi_get_drvdata(spi);
0257
0258 arizona_dev_exit(arizona);
0259 }
0260
0261 static const struct spi_device_id arizona_spi_ids[] = {
0262 { "wm5102", WM5102 },
0263 { "wm5110", WM5110 },
0264 { "wm8280", WM8280 },
0265 { "wm1831", WM1831 },
0266 { "cs47l24", CS47L24 },
0267 { },
0268 };
0269 MODULE_DEVICE_TABLE(spi, arizona_spi_ids);
0270
0271 #ifdef CONFIG_OF
0272 static const struct of_device_id arizona_spi_of_match[] = {
0273 { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
0274 { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
0275 { .compatible = "wlf,wm8280", .data = (void *)WM8280 },
0276 { .compatible = "wlf,wm1831", .data = (void *)WM1831 },
0277 { .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
0278 {},
0279 };
0280 #endif
0281
0282 static struct spi_driver arizona_spi_driver = {
0283 .driver = {
0284 .name = "arizona",
0285 .pm = &arizona_pm_ops,
0286 .of_match_table = of_match_ptr(arizona_spi_of_match),
0287 .acpi_match_table = ACPI_PTR(arizona_acpi_match),
0288 },
0289 .probe = arizona_spi_probe,
0290 .remove = arizona_spi_remove,
0291 .id_table = arizona_spi_ids,
0292 };
0293
0294 module_spi_driver(arizona_spi_driver);
0295
0296 MODULE_SOFTDEP("pre: arizona_ldo1");
0297 MODULE_DESCRIPTION("Arizona SPI bus interface");
0298 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
0299 MODULE_LICENSE("GPL");