diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/platform/chrome/chromeos_laptop.c | 140 | ||||
| -rw-r--r-- | drivers/platform/chrome/chromeos_pstore.c | 14 |
2 files changed, 132 insertions, 22 deletions
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 67b316b2a2bd..d866db80b4fd 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | #define ISL_ALS_I2C_ADDR 0x44 | 37 | #define ISL_ALS_I2C_ADDR 0x44 |
| 38 | #define TAOS_ALS_I2C_ADDR 0x29 | 38 | #define TAOS_ALS_I2C_ADDR 0x29 |
| 39 | 39 | ||
| 40 | #define MAX_I2C_DEVICE_DEFERRALS 5 | ||
| 41 | |||
| 40 | static struct i2c_client *als; | 42 | static struct i2c_client *als; |
| 41 | static struct i2c_client *tp; | 43 | static struct i2c_client *tp; |
| 42 | static struct i2c_client *ts; | 44 | static struct i2c_client *ts; |
| @@ -45,6 +47,8 @@ static const char *i2c_adapter_names[] = { | |||
| 45 | "SMBus I801 adapter", | 47 | "SMBus I801 adapter", |
| 46 | "i915 gmbus vga", | 48 | "i915 gmbus vga", |
| 47 | "i915 gmbus panel", | 49 | "i915 gmbus panel", |
| 50 | "i2c-designware-pci", | ||
| 51 | "i2c-designware-pci", | ||
| 48 | }; | 52 | }; |
| 49 | 53 | ||
| 50 | /* Keep this enum consistent with i2c_adapter_names */ | 54 | /* Keep this enum consistent with i2c_adapter_names */ |
| @@ -52,11 +56,21 @@ enum i2c_adapter_type { | |||
| 52 | I2C_ADAPTER_SMBUS = 0, | 56 | I2C_ADAPTER_SMBUS = 0, |
| 53 | I2C_ADAPTER_VGADDC, | 57 | I2C_ADAPTER_VGADDC, |
| 54 | I2C_ADAPTER_PANEL, | 58 | I2C_ADAPTER_PANEL, |
| 59 | I2C_ADAPTER_DESIGNWARE_0, | ||
| 60 | I2C_ADAPTER_DESIGNWARE_1, | ||
| 61 | }; | ||
| 62 | |||
| 63 | enum i2c_peripheral_state { | ||
| 64 | UNPROBED = 0, | ||
| 65 | PROBED, | ||
| 66 | TIMEDOUT, | ||
| 55 | }; | 67 | }; |
| 56 | 68 | ||
| 57 | struct i2c_peripheral { | 69 | struct i2c_peripheral { |
| 58 | int (*add)(enum i2c_adapter_type type); | 70 | int (*add)(enum i2c_adapter_type type); |
| 59 | enum i2c_adapter_type type; | 71 | enum i2c_adapter_type type; |
| 72 | enum i2c_peripheral_state state; | ||
| 73 | int tries; | ||
| 60 | }; | 74 | }; |
| 61 | 75 | ||
| 62 | #define MAX_I2C_PERIPHERALS 3 | 76 | #define MAX_I2C_PERIPHERALS 3 |
| @@ -158,8 +172,8 @@ static struct i2c_client *__add_probed_i2c_device( | |||
| 158 | /* add the i2c device */ | 172 | /* add the i2c device */ |
| 159 | client = i2c_new_probed_device(adapter, info, addrs, NULL); | 173 | client = i2c_new_probed_device(adapter, info, addrs, NULL); |
| 160 | if (!client) | 174 | if (!client) |
| 161 | pr_err("%s failed to register device %d-%02x\n", | 175 | pr_notice("%s failed to register device %d-%02x\n", |
| 162 | __func__, bus, info->addr); | 176 | __func__, bus, info->addr); |
| 163 | else | 177 | else |
| 164 | pr_debug("%s added i2c device %d-%02x\n", | 178 | pr_debug("%s added i2c device %d-%02x\n", |
| 165 | __func__, bus, info->addr); | 179 | __func__, bus, info->addr); |
| @@ -168,29 +182,43 @@ static struct i2c_client *__add_probed_i2c_device( | |||
| 168 | return client; | 182 | return client; |
| 169 | } | 183 | } |
| 170 | 184 | ||
| 185 | struct i2c_lookup { | ||
| 186 | const char *name; | ||
| 187 | int instance; | ||
| 188 | int n; | ||
| 189 | }; | ||
| 190 | |||
| 171 | static int __find_i2c_adap(struct device *dev, void *data) | 191 | static int __find_i2c_adap(struct device *dev, void *data) |
| 172 | { | 192 | { |
| 173 | const char *name = data; | 193 | struct i2c_lookup *lookup = data; |
| 174 | static const char *prefix = "i2c-"; | 194 | static const char *prefix = "i2c-"; |
| 175 | struct i2c_adapter *adapter; | 195 | struct i2c_adapter *adapter; |
| 196 | |||
| 176 | if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) | 197 | if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) |
| 177 | return 0; | 198 | return 0; |
| 178 | adapter = to_i2c_adapter(dev); | 199 | adapter = to_i2c_adapter(dev); |
| 179 | return (strncmp(adapter->name, name, strlen(name)) == 0); | 200 | if (strncmp(adapter->name, lookup->name, strlen(lookup->name)) == 0 && |
| 201 | lookup->n++ == lookup->instance) | ||
| 202 | return 1; | ||
| 203 | return 0; | ||
| 180 | } | 204 | } |
| 181 | 205 | ||
| 182 | static int find_i2c_adapter_num(enum i2c_adapter_type type) | 206 | static int find_i2c_adapter_num(enum i2c_adapter_type type) |
| 183 | { | 207 | { |
| 184 | struct device *dev = NULL; | 208 | struct device *dev = NULL; |
| 185 | struct i2c_adapter *adapter; | 209 | struct i2c_adapter *adapter; |
| 186 | const char *name = i2c_adapter_names[type]; | 210 | struct i2c_lookup lookup; |
| 211 | |||
| 212 | memset(&lookup, 0, sizeof(lookup)); | ||
| 213 | lookup.name = i2c_adapter_names[type]; | ||
| 214 | lookup.instance = (type == I2C_ADAPTER_DESIGNWARE_1) ? 1 : 0; | ||
| 215 | |||
| 187 | /* find the adapter by name */ | 216 | /* find the adapter by name */ |
| 188 | dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, | 217 | dev = bus_find_device(&i2c_bus_type, NULL, &lookup, __find_i2c_adap); |
| 189 | __find_i2c_adap); | ||
| 190 | if (!dev) { | 218 | if (!dev) { |
| 191 | /* Adapters may appear later. Deferred probing will retry */ | 219 | /* Adapters may appear later. Deferred probing will retry */ |
| 192 | pr_notice("%s: i2c adapter %s not found on system.\n", __func__, | 220 | pr_notice("%s: i2c adapter %s not found on system.\n", __func__, |
| 193 | name); | 221 | lookup.name); |
| 194 | return -ENODEV; | 222 | return -ENODEV; |
| 195 | } | 223 | } |
| 196 | adapter = to_i2c_adapter(dev); | 224 | adapter = to_i2c_adapter(dev); |
| @@ -227,6 +255,7 @@ static struct i2c_client *add_i2c_device(const char *name, | |||
| 227 | struct i2c_board_info *info) | 255 | struct i2c_board_info *info) |
| 228 | { | 256 | { |
| 229 | const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END }; | 257 | const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END }; |
| 258 | |||
| 230 | return __add_probed_i2c_device(name, | 259 | return __add_probed_i2c_device(name, |
| 231 | find_i2c_adapter_num(type), | 260 | find_i2c_adapter_num(type), |
| 232 | info, | 261 | info, |
| @@ -324,9 +353,36 @@ static int chromeos_laptop_probe(struct platform_device *pdev) | |||
| 324 | if (i2c_dev->add == NULL) | 353 | if (i2c_dev->add == NULL) |
| 325 | break; | 354 | break; |
| 326 | 355 | ||
| 327 | /* Add the device. Set -EPROBE_DEFER on any failure */ | 356 | if (i2c_dev->state == TIMEDOUT || i2c_dev->state == PROBED) |
| 328 | if (i2c_dev->add(i2c_dev->type)) | 357 | continue; |
| 358 | |||
| 359 | /* | ||
| 360 | * Check that the i2c adapter is present. | ||
| 361 | * -EPROBE_DEFER if missing as the adapter may appear much | ||
| 362 | * later. | ||
| 363 | */ | ||
| 364 | if (find_i2c_adapter_num(i2c_dev->type) == -ENODEV) { | ||
| 329 | ret = -EPROBE_DEFER; | 365 | ret = -EPROBE_DEFER; |
| 366 | continue; | ||
| 367 | } | ||
| 368 | |||
| 369 | /* Add the device. */ | ||
| 370 | if (i2c_dev->add(i2c_dev->type) == -EAGAIN) { | ||
| 371 | /* | ||
| 372 | * Set -EPROBE_DEFER a limited num of times | ||
| 373 | * if device is not successfully added. | ||
| 374 | */ | ||
| 375 | if (++i2c_dev->tries < MAX_I2C_DEVICE_DEFERRALS) { | ||
| 376 | ret = -EPROBE_DEFER; | ||
| 377 | } else { | ||
| 378 | /* Ran out of tries. */ | ||
| 379 | pr_notice("%s: Ran out of tries for device.\n", | ||
| 380 | __func__); | ||
| 381 | i2c_dev->state = TIMEDOUT; | ||
| 382 | } | ||
| 383 | } else { | ||
| 384 | i2c_dev->state = PROBED; | ||
| 385 | } | ||
| 330 | } | 386 | } |
| 331 | 387 | ||
| 332 | return ret; | 388 | return ret; |
| @@ -359,6 +415,27 @@ static struct chromeos_laptop chromebook_pixel = { | |||
| 359 | }, | 415 | }, |
| 360 | }; | 416 | }; |
| 361 | 417 | ||
| 418 | static struct chromeos_laptop hp_chromebook_14 = { | ||
| 419 | .i2c_peripherals = { | ||
| 420 | /* Touchpad. */ | ||
| 421 | { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, | ||
| 422 | }, | ||
| 423 | }; | ||
| 424 | |||
| 425 | static struct chromeos_laptop dell_chromebook_11 = { | ||
| 426 | .i2c_peripherals = { | ||
| 427 | /* Touchpad. */ | ||
| 428 | { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, | ||
| 429 | }, | ||
| 430 | }; | ||
| 431 | |||
| 432 | static struct chromeos_laptop toshiba_cb35 = { | ||
| 433 | .i2c_peripherals = { | ||
| 434 | /* Touchpad. */ | ||
| 435 | { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, | ||
| 436 | }, | ||
| 437 | }; | ||
| 438 | |||
| 362 | static struct chromeos_laptop acer_c7_chromebook = { | 439 | static struct chromeos_laptop acer_c7_chromebook = { |
| 363 | .i2c_peripherals = { | 440 | .i2c_peripherals = { |
| 364 | /* Touchpad. */ | 441 | /* Touchpad. */ |
| @@ -373,6 +450,17 @@ static struct chromeos_laptop acer_ac700 = { | |||
| 373 | }, | 450 | }, |
| 374 | }; | 451 | }; |
| 375 | 452 | ||
| 453 | static struct chromeos_laptop acer_c720 = { | ||
| 454 | .i2c_peripherals = { | ||
| 455 | /* Touchscreen. */ | ||
| 456 | { .add = setup_atmel_1664s_ts, I2C_ADAPTER_DESIGNWARE_1 }, | ||
| 457 | /* Touchpad. */ | ||
| 458 | { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, | ||
| 459 | /* Light Sensor. */ | ||
| 460 | { .add = setup_isl29018_als, I2C_ADAPTER_DESIGNWARE_1 }, | ||
| 461 | }, | ||
| 462 | }; | ||
| 463 | |||
| 376 | static struct chromeos_laptop hp_pavilion_14_chromebook = { | 464 | static struct chromeos_laptop hp_pavilion_14_chromebook = { |
| 377 | .i2c_peripherals = { | 465 | .i2c_peripherals = { |
| 378 | /* Touchpad. */ | 466 | /* Touchpad. */ |
| @@ -416,6 +504,30 @@ static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = { | |||
| 416 | _CBDD(chromebook_pixel), | 504 | _CBDD(chromebook_pixel), |
| 417 | }, | 505 | }, |
| 418 | { | 506 | { |
| 507 | .ident = "Wolf", | ||
| 508 | .matches = { | ||
| 509 | DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), | ||
| 510 | DMI_MATCH(DMI_PRODUCT_NAME, "Wolf"), | ||
| 511 | }, | ||
| 512 | _CBDD(dell_chromebook_11), | ||
| 513 | }, | ||
| 514 | { | ||
| 515 | .ident = "HP Chromebook 14", | ||
| 516 | .matches = { | ||
| 517 | DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), | ||
| 518 | DMI_MATCH(DMI_PRODUCT_NAME, "Falco"), | ||
| 519 | }, | ||
| 520 | _CBDD(hp_chromebook_14), | ||
| 521 | }, | ||
| 522 | { | ||
| 523 | .ident = "Toshiba CB35", | ||
| 524 | .matches = { | ||
| 525 | DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), | ||
| 526 | DMI_MATCH(DMI_PRODUCT_NAME, "Leon"), | ||
| 527 | }, | ||
| 528 | _CBDD(toshiba_cb35), | ||
| 529 | }, | ||
| 530 | { | ||
| 419 | .ident = "Acer C7 Chromebook", | 531 | .ident = "Acer C7 Chromebook", |
| 420 | .matches = { | 532 | .matches = { |
| 421 | DMI_MATCH(DMI_PRODUCT_NAME, "Parrot"), | 533 | DMI_MATCH(DMI_PRODUCT_NAME, "Parrot"), |
| @@ -430,6 +542,13 @@ static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = { | |||
| 430 | _CBDD(acer_ac700), | 542 | _CBDD(acer_ac700), |
| 431 | }, | 543 | }, |
| 432 | { | 544 | { |
| 545 | .ident = "Acer C720", | ||
| 546 | .matches = { | ||
| 547 | DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"), | ||
| 548 | }, | ||
| 549 | _CBDD(acer_c720), | ||
| 550 | }, | ||
| 551 | { | ||
| 433 | .ident = "HP Pavilion 14 Chromebook", | 552 | .ident = "HP Pavilion 14 Chromebook", |
| 434 | .matches = { | 553 | .matches = { |
| 435 | DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"), | 554 | DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"), |
| @@ -460,6 +579,7 @@ static struct platform_driver cros_platform_driver = { | |||
| 460 | static int __init chromeos_laptop_init(void) | 579 | static int __init chromeos_laptop_init(void) |
| 461 | { | 580 | { |
| 462 | int ret; | 581 | int ret; |
| 582 | |||
| 463 | if (!dmi_check_system(chromeos_laptop_dmi_table)) { | 583 | if (!dmi_check_system(chromeos_laptop_dmi_table)) { |
| 464 | pr_debug("%s unsupported system.\n", __func__); | 584 | pr_debug("%s unsupported system.\n", __func__); |
| 465 | return -ENODEV; | 585 | return -ENODEV; |
diff --git a/drivers/platform/chrome/chromeos_pstore.c b/drivers/platform/chrome/chromeos_pstore.c index e0e0e65cf442..34749200e4ab 100644 --- a/drivers/platform/chrome/chromeos_pstore.c +++ b/drivers/platform/chrome/chromeos_pstore.c | |||
| @@ -16,23 +16,13 @@ | |||
| 16 | static struct dmi_system_id chromeos_pstore_dmi_table[] __initdata = { | 16 | static struct dmi_system_id chromeos_pstore_dmi_table[] __initdata = { |
| 17 | { | 17 | { |
| 18 | /* | 18 | /* |
| 19 | * Today all Chromebooks/boxes ship with GOOGLE as vendor and | 19 | * Today all Chromebooks/boxes ship with Google_* as version and |
| 20 | * coreboot as bios vendor. No other systems with this | 20 | * coreboot as bios vendor. No other systems with this |
| 21 | * combination are known to date. | 21 | * combination are known to date. |
| 22 | */ | 22 | */ |
| 23 | .matches = { | 23 | .matches = { |
| 24 | DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), | ||
| 25 | DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), | ||
| 26 | }, | ||
| 27 | }, | ||
| 28 | { | ||
| 29 | /* | ||
| 30 | * The first Samsung Chromebox and Chromebook Series 5 550 use | ||
| 31 | * coreboot but with Samsung as the system vendor. | ||
| 32 | */ | ||
| 33 | .matches = { | ||
| 34 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"), | ||
| 35 | DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), | 24 | DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), |
| 25 | DMI_MATCH(DMI_BIOS_VERSION, "Google_"), | ||
| 36 | }, | 26 | }, |
| 37 | }, | 27 | }, |
| 38 | { | 28 | { |
