0001
0002
0003
0004 #include <linux/acpi.h>
0005 #include <linux/clkdev.h>
0006 #include <linux/clk-provider.h>
0007 #include <linux/device.h>
0008 #include <linux/gpio/consumer.h>
0009 #include <linux/gpio/machine.h>
0010 #include <linux/i2c.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/overflow.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/uuid.h>
0016
0017 #include "common.h"
0018
0019
0020
0021
0022
0023
0024
0025
0026 static const guid_t int3472_gpio_guid =
0027 GUID_INIT(0x79234640, 0x9e10, 0x4fea,
0028 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f);
0029
0030
0031
0032
0033
0034
0035 static const guid_t cio2_sensor_module_guid =
0036 GUID_INIT(0x822ace8f, 0x2814, 0x4174,
0037 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee);
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 static const struct int3472_gpio_function_remap ov2680_gpio_function_remaps[] = {
0053 { "reset", NULL },
0054 { "powerdown", "reset" },
0055 { }
0056 };
0057
0058 static const struct int3472_sensor_config int3472_sensor_configs[] = {
0059
0060 { "GNDF140809R", { 0 }, ov2680_gpio_function_remaps },
0061
0062 { "GEFF150023R", REGULATOR_SUPPLY("avdd", NULL), NULL },
0063
0064 { "YHCU", REGULATOR_SUPPLY("avdd", NULL), NULL },
0065 };
0066
0067 static const struct int3472_sensor_config *
0068 skl_int3472_get_sensor_module_config(struct int3472_discrete_device *int3472)
0069 {
0070 union acpi_object *obj;
0071 unsigned int i;
0072
0073 obj = acpi_evaluate_dsm_typed(int3472->sensor->handle,
0074 &cio2_sensor_module_guid, 0x00,
0075 0x01, NULL, ACPI_TYPE_STRING);
0076
0077 if (!obj) {
0078 dev_err(int3472->dev,
0079 "Failed to get sensor module string from _DSM\n");
0080 return ERR_PTR(-ENODEV);
0081 }
0082
0083 if (obj->string.type != ACPI_TYPE_STRING) {
0084 dev_err(int3472->dev,
0085 "Sensor _DSM returned a non-string value\n");
0086
0087 ACPI_FREE(obj);
0088 return ERR_PTR(-EINVAL);
0089 }
0090
0091 for (i = 0; i < ARRAY_SIZE(int3472_sensor_configs); i++) {
0092 if (!strcmp(int3472_sensor_configs[i].sensor_module_name,
0093 obj->string.pointer))
0094 break;
0095 }
0096
0097 ACPI_FREE(obj);
0098
0099 if (i >= ARRAY_SIZE(int3472_sensor_configs))
0100 return ERR_PTR(-EINVAL);
0101
0102 return &int3472_sensor_configs[i];
0103 }
0104
0105 static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int3472,
0106 struct acpi_resource_gpio *agpio,
0107 const char *func, u32 polarity)
0108 {
0109 const struct int3472_sensor_config *sensor_config;
0110 char *path = agpio->resource_source.string_ptr;
0111 struct gpiod_lookup *table_entry;
0112 struct acpi_device *adev;
0113 acpi_handle handle;
0114 acpi_status status;
0115
0116 if (int3472->n_sensor_gpios >= INT3472_MAX_SENSOR_GPIOS) {
0117 dev_warn(int3472->dev, "Too many GPIOs mapped\n");
0118 return -EINVAL;
0119 }
0120
0121 sensor_config = int3472->sensor_config;
0122 if (!IS_ERR(sensor_config) && sensor_config->function_maps) {
0123 const struct int3472_gpio_function_remap *remap;
0124
0125 for (remap = sensor_config->function_maps; remap->documented; remap++) {
0126 if (!strcmp(func, remap->documented)) {
0127 func = remap->actual;
0128 break;
0129 }
0130 }
0131 }
0132
0133
0134 if (!func)
0135 return 0;
0136
0137 status = acpi_get_handle(NULL, path, &handle);
0138 if (ACPI_FAILURE(status))
0139 return -EINVAL;
0140
0141 adev = acpi_fetch_acpi_dev(handle);
0142 if (!adev)
0143 return -ENODEV;
0144
0145 table_entry = &int3472->gpios.table[int3472->n_sensor_gpios];
0146 table_entry->key = acpi_dev_name(adev);
0147 table_entry->chip_hwnum = agpio->pin_table[0];
0148 table_entry->con_id = func;
0149 table_entry->idx = 0;
0150 table_entry->flags = polarity;
0151
0152 int3472->n_sensor_gpios++;
0153
0154 return 0;
0155 }
0156
0157 static int skl_int3472_map_gpio_to_clk(struct int3472_discrete_device *int3472,
0158 struct acpi_resource_gpio *agpio, u8 type)
0159 {
0160 char *path = agpio->resource_source.string_ptr;
0161 u16 pin = agpio->pin_table[0];
0162 struct gpio_desc *gpio;
0163
0164 switch (type) {
0165 case INT3472_GPIO_TYPE_CLK_ENABLE:
0166 gpio = acpi_get_and_request_gpiod(path, pin, "int3472,clk-enable");
0167 if (IS_ERR(gpio))
0168 return (PTR_ERR(gpio));
0169
0170 int3472->clock.ena_gpio = gpio;
0171 break;
0172 case INT3472_GPIO_TYPE_PRIVACY_LED:
0173 gpio = acpi_get_and_request_gpiod(path, pin, "int3472,privacy-led");
0174 if (IS_ERR(gpio))
0175 return (PTR_ERR(gpio));
0176
0177 int3472->clock.led_gpio = gpio;
0178 break;
0179 default:
0180 dev_err(int3472->dev, "Invalid GPIO type 0x%02x for clock\n", type);
0181 break;
0182 }
0183
0184 return 0;
0185 }
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
0220 void *data)
0221 {
0222 struct int3472_discrete_device *int3472 = data;
0223 struct acpi_resource_gpio *agpio;
0224 union acpi_object *obj;
0225 const char *err_msg;
0226 int ret;
0227 u8 type;
0228
0229 if (!acpi_gpio_get_io_resource(ares, &agpio))
0230 return 1;
0231
0232
0233
0234
0235
0236 obj = acpi_evaluate_dsm_typed(int3472->adev->handle,
0237 &int3472_gpio_guid, 0x00,
0238 int3472->ngpios + 2,
0239 NULL, ACPI_TYPE_INTEGER);
0240
0241 if (!obj) {
0242 dev_warn(int3472->dev, "No _DSM entry for GPIO pin %u\n",
0243 agpio->pin_table[0]);
0244 return 1;
0245 }
0246
0247 type = obj->integer.value & 0xff;
0248
0249 switch (type) {
0250 case INT3472_GPIO_TYPE_RESET:
0251 ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "reset",
0252 GPIO_ACTIVE_LOW);
0253 if (ret)
0254 err_msg = "Failed to map reset pin to sensor\n";
0255
0256 break;
0257 case INT3472_GPIO_TYPE_POWERDOWN:
0258 ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "powerdown",
0259 GPIO_ACTIVE_LOW);
0260 if (ret)
0261 err_msg = "Failed to map powerdown pin to sensor\n";
0262
0263 break;
0264 case INT3472_GPIO_TYPE_CLK_ENABLE:
0265 case INT3472_GPIO_TYPE_PRIVACY_LED:
0266 ret = skl_int3472_map_gpio_to_clk(int3472, agpio, type);
0267 if (ret)
0268 err_msg = "Failed to map GPIO to clock\n";
0269
0270 break;
0271 case INT3472_GPIO_TYPE_POWER_ENABLE:
0272 ret = skl_int3472_register_regulator(int3472, agpio);
0273 if (ret)
0274 err_msg = "Failed to map regulator to sensor\n";
0275
0276 break;
0277 default:
0278 dev_warn(int3472->dev,
0279 "GPIO type 0x%02x unknown; the sensor may not work\n",
0280 type);
0281 ret = 1;
0282 break;
0283 }
0284
0285 int3472->ngpios++;
0286 ACPI_FREE(obj);
0287
0288 if (ret < 0)
0289 return dev_err_probe(int3472->dev, ret, err_msg);
0290
0291 return ret;
0292 }
0293
0294 static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
0295 {
0296 LIST_HEAD(resource_list);
0297 int ret;
0298
0299
0300
0301
0302
0303 int3472->sensor_config = skl_int3472_get_sensor_module_config(int3472);
0304
0305 ret = acpi_dev_get_resources(int3472->adev, &resource_list,
0306 skl_int3472_handle_gpio_resources,
0307 int3472);
0308 if (ret < 0)
0309 return ret;
0310
0311 acpi_dev_free_resource_list(&resource_list);
0312
0313
0314
0315
0316
0317
0318 if (int3472->clock.ena_gpio) {
0319 ret = skl_int3472_register_clock(int3472);
0320 if (ret)
0321 return ret;
0322 } else {
0323 if (int3472->clock.led_gpio)
0324 dev_warn(int3472->dev,
0325 "No clk GPIO. The privacy LED won't work\n");
0326 }
0327
0328 int3472->gpios.dev_id = int3472->sensor_name;
0329 gpiod_add_lookup_table(&int3472->gpios);
0330
0331 return 0;
0332 }
0333
0334 static int skl_int3472_discrete_remove(struct platform_device *pdev);
0335
0336 static int skl_int3472_discrete_probe(struct platform_device *pdev)
0337 {
0338 struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
0339 struct int3472_discrete_device *int3472;
0340 struct int3472_cldb cldb;
0341 int ret;
0342
0343 ret = skl_int3472_fill_cldb(adev, &cldb);
0344 if (ret) {
0345 dev_err(&pdev->dev, "Couldn't fill CLDB structure\n");
0346 return ret;
0347 }
0348
0349 if (cldb.control_logic_type != 1) {
0350 dev_err(&pdev->dev, "Unsupported control logic type %u\n",
0351 cldb.control_logic_type);
0352 return -EINVAL;
0353 }
0354
0355
0356 int3472 = devm_kzalloc(&pdev->dev, struct_size(int3472, gpios.table,
0357 INT3472_MAX_SENSOR_GPIOS + 1), GFP_KERNEL);
0358 if (!int3472)
0359 return -ENOMEM;
0360
0361 int3472->adev = adev;
0362 int3472->dev = &pdev->dev;
0363 platform_set_drvdata(pdev, int3472);
0364
0365 ret = skl_int3472_get_sensor_adev_and_name(&pdev->dev, &int3472->sensor,
0366 &int3472->sensor_name);
0367 if (ret)
0368 return ret;
0369
0370
0371
0372
0373
0374 INIT_LIST_HEAD(&int3472->gpios.list);
0375
0376 ret = skl_int3472_parse_crs(int3472);
0377 if (ret) {
0378 skl_int3472_discrete_remove(pdev);
0379 return ret;
0380 }
0381
0382 acpi_dev_clear_dependencies(adev);
0383 return 0;
0384 }
0385
0386 static int skl_int3472_discrete_remove(struct platform_device *pdev)
0387 {
0388 struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
0389
0390 gpiod_remove_lookup_table(&int3472->gpios);
0391
0392 if (int3472->clock.cl)
0393 skl_int3472_unregister_clock(int3472);
0394
0395 gpiod_put(int3472->clock.ena_gpio);
0396 gpiod_put(int3472->clock.led_gpio);
0397
0398 skl_int3472_unregister_regulator(int3472);
0399
0400 return 0;
0401 }
0402
0403 static const struct acpi_device_id int3472_device_id[] = {
0404 { "INT3472", 0 },
0405 { }
0406 };
0407 MODULE_DEVICE_TABLE(acpi, int3472_device_id);
0408
0409 static struct platform_driver int3472_discrete = {
0410 .driver = {
0411 .name = "int3472-discrete",
0412 .acpi_match_table = int3472_device_id,
0413 },
0414 .probe = skl_int3472_discrete_probe,
0415 .remove = skl_int3472_discrete_remove,
0416 };
0417 module_platform_driver(int3472_discrete);
0418
0419 MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Discrete Device Driver");
0420 MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
0421 MODULE_LICENSE("GPL v2");