Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'chrome-platform-for-linus-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/bleung/chrome-platform

Pull chrome platform updates from Benson Leung:

- a series from Dmitry to remove platform data from chromeos_laptop.c,
which was the only user of platform data for the atmel_mxt_ts driver.

- a series to clean up sysfs and debugfs for cros_ec

- other misc cleanups

* tag 'chrome-platform-for-linus-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/bleung/chrome-platform: (22 commits)
platform/chrome: mfd/cros_ec_dev: Add sysfs entry to set keyboard wake lid angle
platform/chrome: cros_ec_debugfs: Add PD port info to debugfs
platform/chrome: cros_ec_debugfs: Use octal permissions '0444'
platform/chrome: cros_ec_sysfs: use permission-specific DEVICE_ATTR variants
platform/chrome: cros_ec_sysfs: introduce to_cros_ec_dev define.
platform/chrome: cros_ec_sysfs: Modify error handling
platform/chrome: cros_ec_lpc: Add support for Google devices using custom coreboot firmware
platform/chrome: cros_ec_lpc: wake up from s2idle on Chrome EC
Input: atmel_mxt_ts - remove platform data support
platform/chrome: chromeos_laptop - discard data for unneeded boards
platform/chrome: chromeos_laptop - use device properties for Pixel
platform/chrome: chromeos_laptop - rely on I2C to set up interrupt trigger
platform/chrome: chromeos_laptop - use I2C notifier to create devices
platform/chrome: chromeos_laptop - parse DMI IRQ data once
platform/chrome: chromeos_laptop - rework i2c peripherals initialization
platform/chrome: chromeos_laptop - factor out getting IRQ from DMI
platform/chrome: chromeos_laptop - introduce pr_fmt()
platform/chrome: chromeos_laptop - stop setting suspend mode for Atmel devices
platform/chrome: chromeos_laptop - add SPDX identifier
Input: atmel_mxt_ts - switch ChromeOS ACPI devices to generic props
...

+849 -699
-1
MAINTAINERS
··· 2426 2426 S: Maintained 2427 2427 F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt 2428 2428 F: drivers/input/touchscreen/atmel_mxt_ts.c 2429 - F: include/linux/platform_data/atmel_mxt_ts.h 2430 2429 2431 2430 ATMEL SAMA5D2 ADC DRIVER 2432 2431 M: Ludovic Desroches <ludovic.desroches@microchip.com>
+139 -124
drivers/input/touchscreen/atmel_mxt_ts.c
··· 23 23 #include <linux/delay.h> 24 24 #include <linux/firmware.h> 25 25 #include <linux/i2c.h> 26 - #include <linux/platform_data/atmel_mxt_ts.h> 27 26 #include <linux/input/mt.h> 28 27 #include <linux/interrupt.h> 29 28 #include <linux/of.h> 29 + #include <linux/property.h> 30 30 #include <linux/slab.h> 31 31 #include <linux/gpio/consumer.h> 32 + #include <linux/property.h> 32 33 #include <asm/unaligned.h> 33 34 #include <media/v4l2-device.h> 34 35 #include <media/v4l2-ioctl.h> ··· 269 268 .poll = vb2_fop_poll, 270 269 }; 271 270 271 + enum mxt_suspend_mode { 272 + MXT_SUSPEND_DEEP_SLEEP = 0, 273 + MXT_SUSPEND_T9_CTRL = 1, 274 + }; 275 + 272 276 /* Each client has this additional data */ 273 277 struct mxt_data { 274 278 struct i2c_client *client; 275 279 struct input_dev *input_dev; 276 280 char phys[64]; /* device physical location */ 277 - const struct mxt_platform_data *pdata; 278 281 struct mxt_object *object_table; 279 282 struct mxt_info info; 280 283 unsigned int irq; ··· 329 324 330 325 /* for config update handling */ 331 326 struct completion crc_completion; 327 + 328 + u32 *t19_keymap; 329 + unsigned int t19_num_keys; 330 + 331 + enum mxt_suspend_mode suspend_mode; 332 332 }; 333 333 334 334 struct mxt_vb2_buffer { ··· 752 742 static void mxt_input_button(struct mxt_data *data, u8 *message) 753 743 { 754 744 struct input_dev *input = data->input_dev; 755 - const struct mxt_platform_data *pdata = data->pdata; 756 745 int i; 757 746 758 - for (i = 0; i < pdata->t19_num_keys; i++) { 759 - if (pdata->t19_keymap[i] == KEY_RESERVED) 747 + for (i = 0; i < data->t19_num_keys; i++) { 748 + if (data->t19_keymap[i] == KEY_RESERVED) 760 749 continue; 761 750 762 751 /* Active-low switch */ 763 - input_report_key(input, pdata->t19_keymap[i], 752 + input_report_key(input, data->t19_keymap[i], 764 753 !(message[1] & BIT(i))); 765 754 } 766 755 } ··· 767 758 static void mxt_input_sync(struct mxt_data *data) 768 759 { 769 760 input_mt_report_pointer_emulation(data->input_dev, 770 - data->pdata->t19_num_keys); 761 + data->t19_num_keys); 771 762 input_sync(data->input_dev); 772 763 } 773 764 ··· 1867 1858 static void mxt_set_up_as_touchpad(struct input_dev *input_dev, 1868 1859 struct mxt_data *data) 1869 1860 { 1870 - const struct mxt_platform_data *pdata = data->pdata; 1871 1861 int i; 1872 1862 1873 1863 input_dev->name = "Atmel maXTouch Touchpad"; ··· 1880 1872 input_abs_set_res(input_dev, ABS_MT_POSITION_Y, 1881 1873 MXT_PIXELS_PER_MM); 1882 1874 1883 - for (i = 0; i < pdata->t19_num_keys; i++) 1884 - if (pdata->t19_keymap[i] != KEY_RESERVED) 1875 + for (i = 0; i < data->t19_num_keys; i++) 1876 + if (data->t19_keymap[i] != KEY_RESERVED) 1885 1877 input_set_capability(input_dev, EV_KEY, 1886 - pdata->t19_keymap[i]); 1878 + data->t19_keymap[i]); 1887 1879 } 1888 1880 1889 1881 static int mxt_initialize_input_device(struct mxt_data *data) 1890 1882 { 1891 - const struct mxt_platform_data *pdata = data->pdata; 1892 1883 struct device *dev = &data->client->dev; 1893 1884 struct input_dev *input_dev; 1894 1885 int error; ··· 1953 1946 } 1954 1947 1955 1948 /* If device has buttons we assume it is a touchpad */ 1956 - if (pdata->t19_num_keys) { 1949 + if (data->t19_num_keys) { 1957 1950 mxt_set_up_as_touchpad(input_dev, data); 1958 1951 mt_flags |= INPUT_MT_POINTER; 1959 1952 } else { ··· 2875 2868 2876 2869 static void mxt_start(struct mxt_data *data) 2877 2870 { 2878 - switch (data->pdata->suspend_mode) { 2871 + switch (data->suspend_mode) { 2879 2872 case MXT_SUSPEND_T9_CTRL: 2880 2873 mxt_soft_reset(data); 2881 2874 ··· 2893 2886 mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); 2894 2887 break; 2895 2888 } 2896 - 2897 2889 } 2898 2890 2899 2891 static void mxt_stop(struct mxt_data *data) 2900 2892 { 2901 - switch (data->pdata->suspend_mode) { 2893 + switch (data->suspend_mode) { 2902 2894 case MXT_SUSPEND_T9_CTRL: 2903 2895 /* Touch disable */ 2904 2896 mxt_write_object(data, ··· 2927 2921 mxt_stop(data); 2928 2922 } 2929 2923 2930 - #ifdef CONFIG_OF 2931 - static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client) 2924 + static int mxt_parse_device_properties(struct mxt_data *data) 2932 2925 { 2933 - struct mxt_platform_data *pdata; 2934 - struct device_node *np = client->dev.of_node; 2926 + static const char keymap_property[] = "linux,gpio-keymap"; 2927 + struct device *dev = &data->client->dev; 2935 2928 u32 *keymap; 2936 - int proplen, ret; 2929 + int n_keys; 2930 + int error; 2937 2931 2938 - if (!np) 2939 - return ERR_PTR(-ENOENT); 2932 + if (device_property_present(dev, keymap_property)) { 2933 + n_keys = device_property_read_u32_array(dev, keymap_property, 2934 + NULL, 0); 2935 + if (n_keys <= 0) { 2936 + error = n_keys < 0 ? n_keys : -EINVAL; 2937 + dev_err(dev, "invalid/malformed '%s' property: %d\n", 2938 + keymap_property, error); 2939 + return error; 2940 + } 2940 2941 2941 - pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); 2942 - if (!pdata) 2943 - return ERR_PTR(-ENOMEM); 2944 - 2945 - if (of_find_property(np, "linux,gpio-keymap", &proplen)) { 2946 - pdata->t19_num_keys = proplen / sizeof(u32); 2947 - 2948 - keymap = devm_kzalloc(&client->dev, 2949 - pdata->t19_num_keys * sizeof(keymap[0]), 2950 - GFP_KERNEL); 2942 + keymap = devm_kmalloc_array(dev, n_keys, sizeof(*keymap), 2943 + GFP_KERNEL); 2951 2944 if (!keymap) 2952 - return ERR_PTR(-ENOMEM); 2945 + return -ENOMEM; 2953 2946 2954 - ret = of_property_read_u32_array(np, "linux,gpio-keymap", 2955 - keymap, pdata->t19_num_keys); 2956 - if (ret) 2957 - dev_warn(&client->dev, 2958 - "Couldn't read linux,gpio-keymap: %d\n", ret); 2947 + error = device_property_read_u32_array(dev, keymap_property, 2948 + keymap, n_keys); 2949 + if (error) { 2950 + dev_err(dev, "failed to parse '%s' property: %d\n", 2951 + keymap_property, error); 2952 + return error; 2953 + } 2959 2954 2960 - pdata->t19_keymap = keymap; 2955 + data->t19_keymap = keymap; 2956 + data->t19_num_keys = n_keys; 2961 2957 } 2962 2958 2963 - pdata->suspend_mode = MXT_SUSPEND_DEEP_SLEEP; 2964 - 2965 - return pdata; 2959 + return 0; 2966 2960 } 2967 - #else 2968 - static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client) 2969 - { 2970 - return ERR_PTR(-ENOENT); 2971 - } 2972 - #endif 2973 2961 2974 2962 #ifdef CONFIG_ACPI 2975 2963 2976 2964 struct mxt_acpi_platform_data { 2977 2965 const char *hid; 2978 - struct mxt_platform_data pdata; 2966 + const struct property_entry *props; 2979 2967 }; 2980 2968 2981 2969 static unsigned int samus_touchpad_buttons[] = { ··· 2979 2979 BTN_LEFT 2980 2980 }; 2981 2981 2982 + static const struct property_entry samus_touchpad_props[] = { 2983 + PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", samus_touchpad_buttons), 2984 + { } 2985 + }; 2986 + 2982 2987 static struct mxt_acpi_platform_data samus_platform_data[] = { 2983 2988 { 2984 2989 /* Touchpad */ 2985 2990 .hid = "ATML0000", 2986 - .pdata = { 2987 - .t19_num_keys = ARRAY_SIZE(samus_touchpad_buttons), 2988 - .t19_keymap = samus_touchpad_buttons, 2989 - }, 2991 + .props = samus_touchpad_props, 2990 2992 }, 2991 2993 { 2992 2994 /* Touchscreen */ ··· 3006 3004 BTN_LEFT 3007 3005 }; 3008 3006 3007 + static const struct property_entry chromebook_tp_props[] = { 3008 + PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", chromebook_tp_buttons), 3009 + { } 3010 + }; 3011 + 3009 3012 static struct mxt_acpi_platform_data chromebook_platform_data[] = { 3010 3013 { 3011 3014 /* Touchpad */ 3012 3015 .hid = "ATML0000", 3013 - .pdata = { 3014 - .t19_num_keys = ARRAY_SIZE(chromebook_tp_buttons), 3015 - .t19_keymap = chromebook_tp_buttons, 3016 - }, 3016 + .props = chromebook_tp_props, 3017 3017 }, 3018 3018 { 3019 3019 /* Touchscreen */ ··· 3045 3041 { } 3046 3042 }; 3047 3043 3048 - static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client *client) 3044 + static int mxt_prepare_acpi_properties(struct i2c_client *client) 3049 3045 { 3050 3046 struct acpi_device *adev; 3051 3047 const struct dmi_system_id *system_id; 3052 3048 const struct mxt_acpi_platform_data *acpi_pdata; 3049 + 3050 + adev = ACPI_COMPANION(&client->dev); 3051 + if (!adev) 3052 + return -ENOENT; 3053 + 3054 + system_id = dmi_first_match(mxt_dmi_table); 3055 + if (!system_id) 3056 + return -ENOENT; 3057 + 3058 + acpi_pdata = system_id->driver_data; 3059 + if (!acpi_pdata) 3060 + return -ENOENT; 3061 + 3062 + while (acpi_pdata->hid) { 3063 + if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid)) { 3064 + /* 3065 + * Remove previously installed properties if we 3066 + * are probing this device not for the very first 3067 + * time. 3068 + */ 3069 + device_remove_properties(&client->dev); 3070 + 3071 + /* 3072 + * Now install the platform-specific properties 3073 + * that are missing from ACPI. 3074 + */ 3075 + device_add_properties(&client->dev, acpi_pdata->props); 3076 + break; 3077 + } 3078 + 3079 + acpi_pdata++; 3080 + } 3081 + 3082 + return 0; 3083 + } 3084 + #else 3085 + static int mxt_prepare_acpi_properties(struct i2c_client *client) 3086 + { 3087 + return -ENOENT; 3088 + } 3089 + #endif 3090 + 3091 + static const struct dmi_system_id chromebook_T9_suspend_dmi[] = { 3092 + { 3093 + .matches = { 3094 + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 3095 + DMI_MATCH(DMI_PRODUCT_NAME, "Link"), 3096 + }, 3097 + }, 3098 + { 3099 + .matches = { 3100 + DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"), 3101 + }, 3102 + }, 3103 + { } 3104 + }; 3105 + 3106 + static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) 3107 + { 3108 + struct mxt_data *data; 3109 + int error; 3053 3110 3054 3111 /* 3055 3112 * Ignore ACPI devices representing bootloader mode. ··· 3122 3057 * application mode addresses were all above 0x40, so we'll use it 3123 3058 * as a threshold. 3124 3059 */ 3125 - if (client->addr < 0x40) 3126 - return ERR_PTR(-ENXIO); 3127 - 3128 - adev = ACPI_COMPANION(&client->dev); 3129 - if (!adev) 3130 - return ERR_PTR(-ENOENT); 3131 - 3132 - system_id = dmi_first_match(mxt_dmi_table); 3133 - if (!system_id) 3134 - return ERR_PTR(-ENOENT); 3135 - 3136 - acpi_pdata = system_id->driver_data; 3137 - if (!acpi_pdata) 3138 - return ERR_PTR(-ENOENT); 3139 - 3140 - while (acpi_pdata->hid) { 3141 - if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid)) 3142 - return &acpi_pdata->pdata; 3143 - 3144 - acpi_pdata++; 3145 - } 3146 - 3147 - return ERR_PTR(-ENOENT); 3148 - } 3149 - #else 3150 - static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client *client) 3151 - { 3152 - return ERR_PTR(-ENOENT); 3153 - } 3154 - #endif 3155 - 3156 - static const struct mxt_platform_data * 3157 - mxt_get_platform_data(struct i2c_client *client) 3158 - { 3159 - const struct mxt_platform_data *pdata; 3160 - 3161 - pdata = dev_get_platdata(&client->dev); 3162 - if (pdata) 3163 - return pdata; 3164 - 3165 - pdata = mxt_parse_dt(client); 3166 - if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT) 3167 - return pdata; 3168 - 3169 - pdata = mxt_parse_acpi(client); 3170 - if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT) 3171 - return pdata; 3172 - 3173 - dev_err(&client->dev, "No platform data specified\n"); 3174 - return ERR_PTR(-EINVAL); 3175 - } 3176 - 3177 - static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) 3178 - { 3179 - struct mxt_data *data; 3180 - const struct mxt_platform_data *pdata; 3181 - int error; 3182 - 3183 - pdata = mxt_get_platform_data(client); 3184 - if (IS_ERR(pdata)) 3185 - return PTR_ERR(pdata); 3060 + if (ACPI_COMPANION(&client->dev) && client->addr < 0x40) 3061 + return -ENXIO; 3186 3062 3187 3063 data = devm_kzalloc(&client->dev, sizeof(struct mxt_data), GFP_KERNEL); 3188 3064 if (!data) ··· 3133 3127 client->adapter->nr, client->addr); 3134 3128 3135 3129 data->client = client; 3136 - data->pdata = pdata; 3137 3130 data->irq = client->irq; 3138 3131 i2c_set_clientdata(client, data); 3139 3132 3140 3133 init_completion(&data->bl_completion); 3141 3134 init_completion(&data->reset_completion); 3142 3135 init_completion(&data->crc_completion); 3136 + 3137 + data->suspend_mode = dmi_check_system(chromebook_T9_suspend_dmi) ? 3138 + MXT_SUSPEND_T9_CTRL : MXT_SUSPEND_DEEP_SLEEP; 3139 + 3140 + error = mxt_prepare_acpi_properties(client); 3141 + if (error && error != -ENOENT) 3142 + return error; 3143 + 3144 + error = mxt_parse_device_properties(data); 3145 + if (error) 3146 + return error; 3143 3147 3144 3148 data->reset_gpio = devm_gpiod_get_optional(&client->dev, 3145 3149 "reset", GPIOD_OUT_LOW); ··· 3160 3144 } 3161 3145 3162 3146 error = devm_request_threaded_irq(&client->dev, client->irq, 3163 - NULL, mxt_interrupt, 3164 - pdata->irqflags | IRQF_ONESHOT, 3147 + NULL, mxt_interrupt, IRQF_ONESHOT, 3165 3148 client->name, data); 3166 3149 if (error) { 3167 3150 dev_err(&client->dev, "Failed to register interrupt\n"); ··· 3280 3265 static struct i2c_driver mxt_driver = { 3281 3266 .driver = { 3282 3267 .name = "atmel_mxt_ts", 3283 - .of_match_table = of_match_ptr(mxt_of_match), 3268 + .of_match_table = mxt_of_match, 3284 3269 .acpi_match_table = ACPI_PTR(mxt_acpi_id), 3285 3270 .pm = &mxt_pm_ops, 3286 3271 },
+13 -18
drivers/mfd/cros_ec_dev.c
··· 305 305 306 306 resp = (struct ec_response_motion_sense *)msg->data; 307 307 sensor_num = resp->dump.sensor_count; 308 - /* Allocate 2 extra sensors in case lid angle or FIFO are needed */ 309 - sensor_cells = kzalloc(sizeof(struct mfd_cell) * (sensor_num + 2), 308 + /* Allocate 1 extra sensors in FIFO are needed */ 309 + sensor_cells = kzalloc(sizeof(struct mfd_cell) * (sensor_num + 1), 310 310 GFP_KERNEL); 311 311 if (sensor_cells == NULL) 312 312 goto error; ··· 362 362 sensor_type[resp->info.type]++; 363 363 id++; 364 364 } 365 - if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2) { 366 - sensor_platforms[id].sensor_num = sensor_num; 367 365 368 - sensor_cells[id].name = "cros-ec-angle"; 369 - sensor_cells[id].id = 0; 370 - sensor_cells[id].platform_data = &sensor_platforms[id]; 371 - sensor_cells[id].pdata_size = 372 - sizeof(struct cros_ec_sensor_platform); 373 - id++; 374 - } 366 + if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2) 367 + ec->has_kb_wake_angle = true; 368 + 375 369 if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { 376 370 sensor_cells[id].name = "cros-ec-ring"; 377 371 id++; ··· 418 424 goto failed; 419 425 } 420 426 427 + /* check whether this EC is a sensor hub. */ 428 + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) 429 + cros_ec_sensors_register(ec); 430 + 431 + /* Take control of the lightbar from the EC. */ 432 + lb_manual_suspend_ctrl(ec, 1); 433 + 434 + /* We can now add the sysfs class, we know which parameter to show */ 421 435 retval = cdev_device_add(&ec->cdev, &ec->class_dev); 422 436 if (retval) { 423 437 dev_err(dev, "cdev_device_add failed => %d\n", retval); ··· 434 432 435 433 if (cros_ec_debugfs_init(ec)) 436 434 dev_warn(dev, "failed to create debugfs directory\n"); 437 - 438 - /* check whether this EC is a sensor hub. */ 439 - if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) 440 - cros_ec_sensors_register(ec); 441 - 442 - /* Take control of the lightbar from the EC. */ 443 - lb_manual_suspend_ctrl(ec, 1); 444 435 445 436 return 0; 446 437
+500 -484
drivers/platform/chrome/chromeos_laptop.c
··· 1 - /* 2 - * chromeos_laptop.c - Driver to instantiate Chromebook i2c/smbus devices. 3 - * 4 - * Author : Benson Leung <bleung@chromium.org> 5 - * 6 - * Copyright (C) 2012 Google, Inc. 7 - * 8 - * This program is free software; you can redistribute it and/or modify 9 - * it under the terms of the GNU General Public License as published by 10 - * the Free Software Foundation; either version 2 of the License, or 11 - * (at your option) any later version. 12 - * 13 - * This program is distributed in the hope that it will be useful, 14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - * GNU General Public License for more details. 17 - * 18 - * You should have received a copy of the GNU General Public License 19 - * along with this program; if not, write to the Free Software 20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 - * 22 - */ 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Driver to instantiate Chromebook i2c/smbus devices. 3 + // 4 + // Copyright (C) 2012 Google, Inc. 5 + // Author: Benson Leung <bleung@chromium.org> 6 + 7 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 23 8 24 9 #include <linux/dmi.h> 25 10 #include <linux/i2c.h> 26 - #include <linux/platform_data/atmel_mxt_ts.h> 27 11 #include <linux/input.h> 28 12 #include <linux/interrupt.h> 13 + #include <linux/ioport.h> 29 14 #include <linux/module.h> 15 + #include <linux/pci.h> 30 16 #include <linux/platform_device.h> 17 + #include <linux/property.h> 31 18 32 19 #define ATMEL_TP_I2C_ADDR 0x4b 33 20 #define ATMEL_TP_I2C_BL_ADDR 0x25 ··· 25 38 #define ISL_ALS_I2C_ADDR 0x44 26 39 #define TAOS_ALS_I2C_ADDR 0x29 27 40 28 - #define MAX_I2C_DEVICE_DEFERRALS 5 29 - 30 - static struct i2c_client *als; 31 - static struct i2c_client *tp; 32 - static struct i2c_client *ts; 33 - 34 41 static const char *i2c_adapter_names[] = { 35 42 "SMBus I801 adapter", 36 43 "i915 gmbus vga", 37 44 "i915 gmbus panel", 38 - "Synopsys DesignWare I2C adapter", 39 45 "Synopsys DesignWare I2C adapter", 40 46 }; 41 47 ··· 37 57 I2C_ADAPTER_SMBUS = 0, 38 58 I2C_ADAPTER_VGADDC, 39 59 I2C_ADAPTER_PANEL, 40 - I2C_ADAPTER_DESIGNWARE_0, 41 - I2C_ADAPTER_DESIGNWARE_1, 42 - }; 43 - 44 - enum i2c_peripheral_state { 45 - UNPROBED = 0, 46 - PROBED, 47 - TIMEDOUT, 60 + I2C_ADAPTER_DESIGNWARE, 48 61 }; 49 62 50 63 struct i2c_peripheral { 51 - int (*add)(enum i2c_adapter_type type); 52 - enum i2c_adapter_type type; 53 - enum i2c_peripheral_state state; 54 - int tries; 55 - }; 64 + struct i2c_board_info board_info; 65 + unsigned short alt_addr; 56 66 57 - #define MAX_I2C_PERIPHERALS 4 67 + const char *dmi_name; 68 + unsigned long irqflags; 69 + struct resource irq_resource; 70 + 71 + enum i2c_adapter_type type; 72 + u32 pci_devid; 73 + 74 + struct i2c_client *client; 75 + }; 58 76 59 77 struct chromeos_laptop { 60 - struct i2c_peripheral i2c_peripherals[MAX_I2C_PERIPHERALS]; 78 + /* 79 + * Note that we can't mark this pointer as const because 80 + * i2c_new_probed_device() changes passed in I2C board info, so. 81 + */ 82 + struct i2c_peripheral *i2c_peripherals; 83 + unsigned int num_i2c_peripherals; 61 84 }; 62 85 63 - static struct chromeos_laptop *cros_laptop; 86 + static const struct chromeos_laptop *cros_laptop; 64 87 65 - static struct i2c_board_info cyapa_device = { 66 - I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), 67 - .flags = I2C_CLIENT_WAKE, 88 + static struct i2c_client * 89 + chromes_laptop_instantiate_i2c_device(struct i2c_adapter *adapter, 90 + struct i2c_board_info *info, 91 + unsigned short alt_addr) 92 + { 93 + const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END }; 94 + struct i2c_client *client; 95 + 96 + /* 97 + * Add the i2c device. If we can't detect it at the primary 98 + * address we scan secondary addresses. In any case the client 99 + * structure gets assigned primary address. 100 + */ 101 + client = i2c_new_probed_device(adapter, info, addr_list, NULL); 102 + if (!client && alt_addr) { 103 + struct i2c_board_info dummy_info = { 104 + I2C_BOARD_INFO("dummy", info->addr), 105 + }; 106 + const unsigned short alt_addr_list[] = { 107 + alt_addr, I2C_CLIENT_END 108 + }; 109 + struct i2c_client *dummy; 110 + 111 + dummy = i2c_new_probed_device(adapter, &dummy_info, 112 + alt_addr_list, NULL); 113 + if (dummy) { 114 + pr_debug("%d-%02x is probed at %02x\n", 115 + adapter->nr, info->addr, dummy->addr); 116 + i2c_unregister_device(dummy); 117 + client = i2c_new_device(adapter, info); 118 + } 119 + } 120 + 121 + if (!client) 122 + pr_debug("failed to register device %d-%02x\n", 123 + adapter->nr, info->addr); 124 + else 125 + pr_debug("added i2c device %d-%02x\n", 126 + adapter->nr, info->addr); 127 + 128 + return client; 129 + } 130 + 131 + static bool chromeos_laptop_match_adapter_devid(struct device *dev, u32 devid) 132 + { 133 + struct pci_dev *pdev; 134 + 135 + if (!dev_is_pci(dev)) 136 + return false; 137 + 138 + pdev = to_pci_dev(dev); 139 + return devid == PCI_DEVID(pdev->bus->number, pdev->devfn); 140 + } 141 + 142 + static void chromeos_laptop_check_adapter(struct i2c_adapter *adapter) 143 + { 144 + struct i2c_peripheral *i2c_dev; 145 + int i; 146 + 147 + for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { 148 + i2c_dev = &cros_laptop->i2c_peripherals[i]; 149 + 150 + /* Skip devices already created */ 151 + if (i2c_dev->client) 152 + continue; 153 + 154 + if (strncmp(adapter->name, i2c_adapter_names[i2c_dev->type], 155 + strlen(i2c_adapter_names[i2c_dev->type]))) 156 + continue; 157 + 158 + if (i2c_dev->pci_devid && 159 + !chromeos_laptop_match_adapter_devid(adapter->dev.parent, 160 + i2c_dev->pci_devid)) { 161 + continue; 162 + } 163 + 164 + i2c_dev->client = 165 + chromes_laptop_instantiate_i2c_device(adapter, 166 + &i2c_dev->board_info, 167 + i2c_dev->alt_addr); 168 + } 169 + } 170 + 171 + static void chromeos_laptop_detach_i2c_client(struct i2c_client *client) 172 + { 173 + struct i2c_peripheral *i2c_dev; 174 + int i; 175 + 176 + for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { 177 + i2c_dev = &cros_laptop->i2c_peripherals[i]; 178 + 179 + if (i2c_dev->client == client) 180 + i2c_dev->client = NULL; 181 + } 182 + } 183 + 184 + static int chromeos_laptop_i2c_notifier_call(struct notifier_block *nb, 185 + unsigned long action, void *data) 186 + { 187 + struct device *dev = data; 188 + 189 + switch (action) { 190 + case BUS_NOTIFY_ADD_DEVICE: 191 + if (dev->type == &i2c_adapter_type) 192 + chromeos_laptop_check_adapter(to_i2c_adapter(dev)); 193 + break; 194 + 195 + case BUS_NOTIFY_REMOVED_DEVICE: 196 + if (dev->type == &i2c_client_type) 197 + chromeos_laptop_detach_i2c_client(to_i2c_client(dev)); 198 + break; 199 + } 200 + 201 + return 0; 202 + } 203 + 204 + static struct notifier_block chromeos_laptop_i2c_notifier = { 205 + .notifier_call = chromeos_laptop_i2c_notifier_call, 68 206 }; 69 207 70 - static struct i2c_board_info elantech_device = { 71 - I2C_BOARD_INFO("elan_i2c", ELAN_TP_I2C_ADDR), 72 - .flags = I2C_CLIENT_WAKE, 73 - }; 208 + #define DECLARE_CROS_LAPTOP(_name) \ 209 + static const struct chromeos_laptop _name __initconst = { \ 210 + .i2c_peripherals = _name##_peripherals, \ 211 + .num_i2c_peripherals = ARRAY_SIZE(_name##_peripherals), \ 212 + } 74 213 75 - static struct i2c_board_info isl_als_device = { 76 - I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), 214 + static struct i2c_peripheral samsung_series_5_550_peripherals[] __initdata = { 215 + /* Touchpad. */ 216 + { 217 + .board_info = { 218 + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), 219 + .flags = I2C_CLIENT_WAKE, 220 + }, 221 + .dmi_name = "trackpad", 222 + .type = I2C_ADAPTER_SMBUS, 223 + }, 224 + /* Light Sensor. */ 225 + { 226 + .board_info = { 227 + I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), 228 + }, 229 + .dmi_name = "lightsensor", 230 + .type = I2C_ADAPTER_SMBUS, 231 + }, 77 232 }; 233 + DECLARE_CROS_LAPTOP(samsung_series_5_550); 78 234 79 - static struct i2c_board_info tsl2583_als_device = { 80 - I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), 235 + static struct i2c_peripheral samsung_series_5_peripherals[] __initdata = { 236 + /* Light Sensor. */ 237 + { 238 + .board_info = { 239 + I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), 240 + }, 241 + .type = I2C_ADAPTER_SMBUS, 242 + }, 81 243 }; 244 + DECLARE_CROS_LAPTOP(samsung_series_5); 82 245 83 - static struct i2c_board_info tsl2563_als_device = { 84 - I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), 85 - }; 86 - 87 - static int mxt_t19_keys[] = { 246 + static const int chromebook_pixel_tp_keys[] __initconst = { 88 247 KEY_RESERVED, 89 248 KEY_RESERVED, 90 249 KEY_RESERVED, ··· 232 113 BTN_LEFT 233 114 }; 234 115 235 - static struct mxt_platform_data atmel_224s_tp_platform_data = { 236 - .irqflags = IRQF_TRIGGER_FALLING, 237 - .t19_num_keys = ARRAY_SIZE(mxt_t19_keys), 238 - .t19_keymap = mxt_t19_keys, 239 - .suspend_mode = MXT_SUSPEND_T9_CTRL, 116 + static const struct property_entry 117 + chromebook_pixel_trackpad_props[] __initconst = { 118 + PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", chromebook_pixel_tp_keys), 119 + { } 240 120 }; 241 121 242 - static struct i2c_board_info atmel_224s_tp_device = { 243 - I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR), 244 - .platform_data = &atmel_224s_tp_platform_data, 245 - .flags = I2C_CLIENT_WAKE, 246 - }; 247 - 248 - static struct mxt_platform_data atmel_1664s_platform_data = { 249 - .irqflags = IRQF_TRIGGER_FALLING, 250 - .suspend_mode = MXT_SUSPEND_T9_CTRL, 251 - }; 252 - 253 - static struct i2c_board_info atmel_1664s_device = { 254 - I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR), 255 - .platform_data = &atmel_1664s_platform_data, 256 - .flags = I2C_CLIENT_WAKE, 257 - }; 258 - 259 - static struct i2c_client *__add_probed_i2c_device( 260 - const char *name, 261 - int bus, 262 - struct i2c_board_info *info, 263 - const unsigned short *alt_addr_list) 264 - { 265 - const struct dmi_device *dmi_dev; 266 - const struct dmi_dev_onboard *dev_data; 267 - struct i2c_adapter *adapter; 268 - struct i2c_client *client = NULL; 269 - const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END }; 270 - 271 - if (bus < 0) 272 - return NULL; 273 - /* 274 - * If a name is specified, look for irq platform information stashed 275 - * in DMI_DEV_TYPE_DEV_ONBOARD by the Chrome OS custom system firmware. 276 - */ 277 - if (name) { 278 - dmi_dev = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD, name, NULL); 279 - if (!dmi_dev) { 280 - pr_err("%s failed to dmi find device %s.\n", 281 - __func__, 282 - name); 283 - return NULL; 284 - } 285 - dev_data = (struct dmi_dev_onboard *)dmi_dev->device_data; 286 - if (!dev_data) { 287 - pr_err("%s failed to get data from dmi for %s.\n", 288 - __func__, name); 289 - return NULL; 290 - } 291 - info->irq = dev_data->instance; 292 - } 293 - 294 - adapter = i2c_get_adapter(bus); 295 - if (!adapter) { 296 - pr_err("%s failed to get i2c adapter %d.\n", __func__, bus); 297 - return NULL; 298 - } 299 - 300 - /* 301 - * Add the i2c device. If we can't detect it at the primary 302 - * address we scan secondary addresses. In any case the client 303 - * structure gets assigned primary address. 304 - */ 305 - client = i2c_new_probed_device(adapter, info, addr_list, NULL); 306 - if (!client && alt_addr_list) { 307 - struct i2c_board_info dummy_info = { 308 - I2C_BOARD_INFO("dummy", info->addr), 309 - }; 310 - struct i2c_client *dummy; 311 - 312 - dummy = i2c_new_probed_device(adapter, &dummy_info, 313 - alt_addr_list, NULL); 314 - if (dummy) { 315 - pr_debug("%s %d-%02x is probed at %02x\n", 316 - __func__, bus, info->addr, dummy->addr); 317 - i2c_unregister_device(dummy); 318 - client = i2c_new_device(adapter, info); 319 - } 320 - } 321 - 322 - if (!client) 323 - pr_notice("%s failed to register device %d-%02x\n", 324 - __func__, bus, info->addr); 325 - else 326 - pr_debug("%s added i2c device %d-%02x\n", 327 - __func__, bus, info->addr); 328 - 329 - i2c_put_adapter(adapter); 330 - return client; 331 - } 332 - 333 - struct i2c_lookup { 334 - const char *name; 335 - int instance; 336 - int n; 337 - }; 338 - 339 - static int __find_i2c_adap(struct device *dev, void *data) 340 - { 341 - struct i2c_lookup *lookup = data; 342 - static const char *prefix = "i2c-"; 343 - struct i2c_adapter *adapter; 344 - 345 - if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) 346 - return 0; 347 - adapter = to_i2c_adapter(dev); 348 - if (strncmp(adapter->name, lookup->name, strlen(lookup->name)) == 0 && 349 - lookup->n++ == lookup->instance) 350 - return 1; 351 - return 0; 352 - } 353 - 354 - static int find_i2c_adapter_num(enum i2c_adapter_type type) 355 - { 356 - struct device *dev = NULL; 357 - struct i2c_adapter *adapter; 358 - struct i2c_lookup lookup; 359 - 360 - memset(&lookup, 0, sizeof(lookup)); 361 - lookup.name = i2c_adapter_names[type]; 362 - lookup.instance = (type == I2C_ADAPTER_DESIGNWARE_1) ? 1 : 0; 363 - 364 - /* find the adapter by name */ 365 - dev = bus_find_device(&i2c_bus_type, NULL, &lookup, __find_i2c_adap); 366 - if (!dev) { 367 - /* Adapters may appear later. Deferred probing will retry */ 368 - pr_notice("%s: i2c adapter %s not found on system.\n", __func__, 369 - lookup.name); 370 - return -ENODEV; 371 - } 372 - adapter = to_i2c_adapter(dev); 373 - return adapter->nr; 374 - } 375 - 376 - /* 377 - * Takes a list of addresses in addrs as such : 378 - * { addr1, ... , addrn, I2C_CLIENT_END }; 379 - * add_probed_i2c_device will use i2c_new_probed_device 380 - * and probe for devices at all of the addresses listed. 381 - * Returns NULL if no devices found. 382 - * See Documentation/i2c/instantiating-devices for more information. 383 - */ 384 - static struct i2c_client *add_probed_i2c_device( 385 - const char *name, 386 - enum i2c_adapter_type type, 387 - struct i2c_board_info *info, 388 - const unsigned short *addrs) 389 - { 390 - return __add_probed_i2c_device(name, 391 - find_i2c_adapter_num(type), 392 - info, 393 - addrs); 394 - } 395 - 396 - /* 397 - * Probes for a device at a single address, the one provided by 398 - * info->addr. 399 - * Returns NULL if no device found. 400 - */ 401 - static struct i2c_client *add_i2c_device(const char *name, 402 - enum i2c_adapter_type type, 403 - struct i2c_board_info *info) 404 - { 405 - return __add_probed_i2c_device(name, 406 - find_i2c_adapter_num(type), 407 - info, 408 - NULL); 409 - } 410 - 411 - static int setup_cyapa_tp(enum i2c_adapter_type type) 412 - { 413 - if (tp) 414 - return 0; 415 - 416 - /* add cyapa touchpad */ 417 - tp = add_i2c_device("trackpad", type, &cyapa_device); 418 - return (!tp) ? -EAGAIN : 0; 419 - } 420 - 421 - static int setup_atmel_224s_tp(enum i2c_adapter_type type) 422 - { 423 - const unsigned short addr_list[] = { ATMEL_TP_I2C_BL_ADDR, 424 - I2C_CLIENT_END }; 425 - if (tp) 426 - return 0; 427 - 428 - /* add atmel mxt touchpad */ 429 - tp = add_probed_i2c_device("trackpad", type, 430 - &atmel_224s_tp_device, addr_list); 431 - return (!tp) ? -EAGAIN : 0; 432 - } 433 - 434 - static int setup_elantech_tp(enum i2c_adapter_type type) 435 - { 436 - if (tp) 437 - return 0; 438 - 439 - /* add elantech touchpad */ 440 - tp = add_i2c_device("trackpad", type, &elantech_device); 441 - return (!tp) ? -EAGAIN : 0; 442 - } 443 - 444 - static int setup_atmel_1664s_ts(enum i2c_adapter_type type) 445 - { 446 - const unsigned short addr_list[] = { ATMEL_TS_I2C_BL_ADDR, 447 - I2C_CLIENT_END }; 448 - if (ts) 449 - return 0; 450 - 451 - /* add atmel mxt touch device */ 452 - ts = add_probed_i2c_device("touchscreen", type, 453 - &atmel_1664s_device, addr_list); 454 - return (!ts) ? -EAGAIN : 0; 455 - } 456 - 457 - static int setup_isl29018_als(enum i2c_adapter_type type) 458 - { 459 - if (als) 460 - return 0; 461 - 462 - /* add isl29018 light sensor */ 463 - als = add_i2c_device("lightsensor", type, &isl_als_device); 464 - return (!als) ? -EAGAIN : 0; 465 - } 466 - 467 - static int setup_tsl2583_als(enum i2c_adapter_type type) 468 - { 469 - if (als) 470 - return 0; 471 - 472 - /* add tsl2583 light sensor */ 473 - als = add_i2c_device(NULL, type, &tsl2583_als_device); 474 - return (!als) ? -EAGAIN : 0; 475 - } 476 - 477 - static int setup_tsl2563_als(enum i2c_adapter_type type) 478 - { 479 - if (als) 480 - return 0; 481 - 482 - /* add tsl2563 light sensor */ 483 - als = add_i2c_device(NULL, type, &tsl2563_als_device); 484 - return (!als) ? -EAGAIN : 0; 485 - } 486 - 487 - static int __init chromeos_laptop_dmi_matched(const struct dmi_system_id *id) 488 - { 489 - cros_laptop = (void *)id->driver_data; 490 - pr_debug("DMI Matched %s.\n", id->ident); 491 - 492 - /* Indicate to dmi_scan that processing is done. */ 493 - return 1; 494 - } 495 - 496 - static int chromeos_laptop_probe(struct platform_device *pdev) 497 - { 498 - int i; 499 - int ret = 0; 500 - 501 - for (i = 0; i < MAX_I2C_PERIPHERALS; i++) { 502 - struct i2c_peripheral *i2c_dev; 503 - 504 - i2c_dev = &cros_laptop->i2c_peripherals[i]; 505 - 506 - /* No more peripherals. */ 507 - if (i2c_dev->add == NULL) 508 - break; 509 - 510 - if (i2c_dev->state == TIMEDOUT || i2c_dev->state == PROBED) 511 - continue; 512 - 513 - /* 514 - * Check that the i2c adapter is present. 515 - * -EPROBE_DEFER if missing as the adapter may appear much 516 - * later. 517 - */ 518 - if (find_i2c_adapter_num(i2c_dev->type) == -ENODEV) { 519 - ret = -EPROBE_DEFER; 520 - continue; 521 - } 522 - 523 - /* Add the device. */ 524 - if (i2c_dev->add(i2c_dev->type) == -EAGAIN) { 525 - /* 526 - * Set -EPROBE_DEFER a limited num of times 527 - * if device is not successfully added. 528 - */ 529 - if (++i2c_dev->tries < MAX_I2C_DEVICE_DEFERRALS) { 530 - ret = -EPROBE_DEFER; 531 - } else { 532 - /* Ran out of tries. */ 533 - pr_notice("%s: Ran out of tries for device.\n", 534 - __func__); 535 - i2c_dev->state = TIMEDOUT; 536 - } 537 - } else { 538 - i2c_dev->state = PROBED; 539 - } 540 - } 541 - 542 - return ret; 543 - } 544 - 545 - static struct chromeos_laptop samsung_series_5_550 = { 546 - .i2c_peripherals = { 547 - /* Touchpad. */ 548 - { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, 549 - /* Light Sensor. */ 550 - { .add = setup_isl29018_als, I2C_ADAPTER_SMBUS }, 122 + static struct i2c_peripheral chromebook_pixel_peripherals[] __initdata = { 123 + /* Touch Screen. */ 124 + { 125 + .board_info = { 126 + I2C_BOARD_INFO("atmel_mxt_ts", 127 + ATMEL_TS_I2C_ADDR), 128 + .flags = I2C_CLIENT_WAKE, 129 + }, 130 + .dmi_name = "touchscreen", 131 + .irqflags = IRQF_TRIGGER_FALLING, 132 + .type = I2C_ADAPTER_PANEL, 133 + .alt_addr = ATMEL_TS_I2C_BL_ADDR, 134 + }, 135 + /* Touchpad. */ 136 + { 137 + .board_info = { 138 + I2C_BOARD_INFO("atmel_mxt_tp", 139 + ATMEL_TP_I2C_ADDR), 140 + .properties = 141 + chromebook_pixel_trackpad_props, 142 + .flags = I2C_CLIENT_WAKE, 143 + }, 144 + .dmi_name = "trackpad", 145 + .irqflags = IRQF_TRIGGER_FALLING, 146 + .type = I2C_ADAPTER_VGADDC, 147 + .alt_addr = ATMEL_TP_I2C_BL_ADDR, 148 + }, 149 + /* Light Sensor. */ 150 + { 151 + .board_info = { 152 + I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), 153 + }, 154 + .dmi_name = "lightsensor", 155 + .type = I2C_ADAPTER_PANEL, 551 156 }, 552 157 }; 158 + DECLARE_CROS_LAPTOP(chromebook_pixel); 553 159 554 - static struct chromeos_laptop samsung_series_5 = { 555 - .i2c_peripherals = { 556 - /* Light Sensor. */ 557 - { .add = setup_tsl2583_als, I2C_ADAPTER_SMBUS }, 160 + static struct i2c_peripheral hp_chromebook_14_peripherals[] __initdata = { 161 + /* Touchpad. */ 162 + { 163 + .board_info = { 164 + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), 165 + .flags = I2C_CLIENT_WAKE, 166 + }, 167 + .dmi_name = "trackpad", 168 + .type = I2C_ADAPTER_DESIGNWARE, 558 169 }, 559 170 }; 171 + DECLARE_CROS_LAPTOP(hp_chromebook_14); 560 172 561 - static struct chromeos_laptop chromebook_pixel = { 562 - .i2c_peripherals = { 563 - /* Touch Screen. */ 564 - { .add = setup_atmel_1664s_ts, I2C_ADAPTER_PANEL }, 565 - /* Touchpad. */ 566 - { .add = setup_atmel_224s_tp, I2C_ADAPTER_VGADDC }, 567 - /* Light Sensor. */ 568 - { .add = setup_isl29018_als, I2C_ADAPTER_PANEL }, 173 + static struct i2c_peripheral dell_chromebook_11_peripherals[] __initdata = { 174 + /* Touchpad. */ 175 + { 176 + .board_info = { 177 + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), 178 + .flags = I2C_CLIENT_WAKE, 179 + }, 180 + .dmi_name = "trackpad", 181 + .type = I2C_ADAPTER_DESIGNWARE, 182 + }, 183 + /* Elan Touchpad option. */ 184 + { 185 + .board_info = { 186 + I2C_BOARD_INFO("elan_i2c", ELAN_TP_I2C_ADDR), 187 + .flags = I2C_CLIENT_WAKE, 188 + }, 189 + .dmi_name = "trackpad", 190 + .type = I2C_ADAPTER_DESIGNWARE, 569 191 }, 570 192 }; 193 + DECLARE_CROS_LAPTOP(dell_chromebook_11); 571 194 572 - static struct chromeos_laptop hp_chromebook_14 = { 573 - .i2c_peripherals = { 574 - /* Touchpad. */ 575 - { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, 195 + static struct i2c_peripheral toshiba_cb35_peripherals[] __initdata = { 196 + /* Touchpad. */ 197 + { 198 + .board_info = { 199 + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), 200 + .flags = I2C_CLIENT_WAKE, 201 + }, 202 + .dmi_name = "trackpad", 203 + .type = I2C_ADAPTER_DESIGNWARE, 576 204 }, 577 205 }; 206 + DECLARE_CROS_LAPTOP(toshiba_cb35); 578 207 579 - static struct chromeos_laptop dell_chromebook_11 = { 580 - .i2c_peripherals = { 581 - /* Touchpad. */ 582 - { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, 583 - /* Elan Touchpad option. */ 584 - { .add = setup_elantech_tp, I2C_ADAPTER_DESIGNWARE_0 }, 208 + static struct i2c_peripheral acer_c7_chromebook_peripherals[] __initdata = { 209 + /* Touchpad. */ 210 + { 211 + .board_info = { 212 + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), 213 + .flags = I2C_CLIENT_WAKE, 214 + }, 215 + .dmi_name = "trackpad", 216 + .type = I2C_ADAPTER_SMBUS, 585 217 }, 586 218 }; 219 + DECLARE_CROS_LAPTOP(acer_c7_chromebook); 587 220 588 - static struct chromeos_laptop toshiba_cb35 = { 589 - .i2c_peripherals = { 590 - /* Touchpad. */ 591 - { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, 221 + static struct i2c_peripheral acer_ac700_peripherals[] __initdata = { 222 + /* Light Sensor. */ 223 + { 224 + .board_info = { 225 + I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), 226 + }, 227 + .type = I2C_ADAPTER_SMBUS, 592 228 }, 593 229 }; 230 + DECLARE_CROS_LAPTOP(acer_ac700); 594 231 595 - static struct chromeos_laptop acer_c7_chromebook = { 596 - .i2c_peripherals = { 597 - /* Touchpad. */ 598 - { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, 232 + static struct i2c_peripheral acer_c720_peripherals[] __initdata = { 233 + /* Touchscreen. */ 234 + { 235 + .board_info = { 236 + I2C_BOARD_INFO("atmel_mxt_ts", 237 + ATMEL_TS_I2C_ADDR), 238 + .flags = I2C_CLIENT_WAKE, 239 + }, 240 + .dmi_name = "touchscreen", 241 + .irqflags = IRQF_TRIGGER_FALLING, 242 + .type = I2C_ADAPTER_DESIGNWARE, 243 + .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x2)), 244 + .alt_addr = ATMEL_TS_I2C_BL_ADDR, 245 + }, 246 + /* Touchpad. */ 247 + { 248 + .board_info = { 249 + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), 250 + .flags = I2C_CLIENT_WAKE, 251 + }, 252 + .dmi_name = "trackpad", 253 + .type = I2C_ADAPTER_DESIGNWARE, 254 + .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x1)), 255 + }, 256 + /* Elan Touchpad option. */ 257 + { 258 + .board_info = { 259 + I2C_BOARD_INFO("elan_i2c", ELAN_TP_I2C_ADDR), 260 + .flags = I2C_CLIENT_WAKE, 261 + }, 262 + .dmi_name = "trackpad", 263 + .type = I2C_ADAPTER_DESIGNWARE, 264 + .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x1)), 265 + }, 266 + /* Light Sensor. */ 267 + { 268 + .board_info = { 269 + I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), 270 + }, 271 + .dmi_name = "lightsensor", 272 + .type = I2C_ADAPTER_DESIGNWARE, 273 + .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x2)), 599 274 }, 600 275 }; 276 + DECLARE_CROS_LAPTOP(acer_c720); 601 277 602 - static struct chromeos_laptop acer_ac700 = { 603 - .i2c_peripherals = { 604 - /* Light Sensor. */ 605 - { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS }, 278 + static struct i2c_peripheral 279 + hp_pavilion_14_chromebook_peripherals[] __initdata = { 280 + /* Touchpad. */ 281 + { 282 + .board_info = { 283 + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), 284 + .flags = I2C_CLIENT_WAKE, 285 + }, 286 + .dmi_name = "trackpad", 287 + .type = I2C_ADAPTER_SMBUS, 606 288 }, 607 289 }; 290 + DECLARE_CROS_LAPTOP(hp_pavilion_14_chromebook); 608 291 609 - static struct chromeos_laptop acer_c720 = { 610 - .i2c_peripherals = { 611 - /* Touchscreen. */ 612 - { .add = setup_atmel_1664s_ts, I2C_ADAPTER_DESIGNWARE_1 }, 613 - /* Touchpad. */ 614 - { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, 615 - /* Elan Touchpad option. */ 616 - { .add = setup_elantech_tp, I2C_ADAPTER_DESIGNWARE_0 }, 617 - /* Light Sensor. */ 618 - { .add = setup_isl29018_als, I2C_ADAPTER_DESIGNWARE_1 }, 292 + static struct i2c_peripheral cr48_peripherals[] __initdata = { 293 + /* Light Sensor. */ 294 + { 295 + .board_info = { 296 + I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), 297 + }, 298 + .type = I2C_ADAPTER_SMBUS, 619 299 }, 620 300 }; 621 - 622 - static struct chromeos_laptop hp_pavilion_14_chromebook = { 623 - .i2c_peripherals = { 624 - /* Touchpad. */ 625 - { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, 626 - }, 627 - }; 628 - 629 - static struct chromeos_laptop cr48 = { 630 - .i2c_peripherals = { 631 - /* Light Sensor. */ 632 - { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS }, 633 - }, 634 - }; 635 - 636 - #define _CBDD(board_) \ 637 - .callback = chromeos_laptop_dmi_matched, \ 638 - .driver_data = (void *)&board_ 301 + DECLARE_CROS_LAPTOP(cr48); 639 302 640 303 static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = { 641 304 { ··· 426 525 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"), 427 526 DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"), 428 527 }, 429 - _CBDD(samsung_series_5_550), 528 + .driver_data = (void *)&samsung_series_5_550, 430 529 }, 431 530 { 432 531 .ident = "Samsung Series 5", 433 532 .matches = { 434 533 DMI_MATCH(DMI_PRODUCT_NAME, "Alex"), 435 534 }, 436 - _CBDD(samsung_series_5), 535 + .driver_data = (void *)&samsung_series_5, 437 536 }, 438 537 { 439 538 .ident = "Chromebook Pixel", ··· 441 540 DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 442 541 DMI_MATCH(DMI_PRODUCT_NAME, "Link"), 443 542 }, 444 - _CBDD(chromebook_pixel), 543 + .driver_data = (void *)&chromebook_pixel, 445 544 }, 446 545 { 447 546 .ident = "Wolf", ··· 449 548 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 450 549 DMI_MATCH(DMI_PRODUCT_NAME, "Wolf"), 451 550 }, 452 - _CBDD(dell_chromebook_11), 551 + .driver_data = (void *)&dell_chromebook_11, 453 552 }, 454 553 { 455 554 .ident = "HP Chromebook 14", ··· 457 556 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 458 557 DMI_MATCH(DMI_PRODUCT_NAME, "Falco"), 459 558 }, 460 - _CBDD(hp_chromebook_14), 559 + .driver_data = (void *)&hp_chromebook_14, 461 560 }, 462 561 { 463 562 .ident = "Toshiba CB35", ··· 465 564 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 466 565 DMI_MATCH(DMI_PRODUCT_NAME, "Leon"), 467 566 }, 468 - _CBDD(toshiba_cb35), 567 + .driver_data = (void *)&toshiba_cb35, 469 568 }, 470 569 { 471 570 .ident = "Acer C7 Chromebook", 472 571 .matches = { 473 572 DMI_MATCH(DMI_PRODUCT_NAME, "Parrot"), 474 573 }, 475 - _CBDD(acer_c7_chromebook), 574 + .driver_data = (void *)&acer_c7_chromebook, 476 575 }, 477 576 { 478 577 .ident = "Acer AC700", 479 578 .matches = { 480 579 DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), 481 580 }, 482 - _CBDD(acer_ac700), 581 + .driver_data = (void *)&acer_ac700, 483 582 }, 484 583 { 485 584 .ident = "Acer C720", 486 585 .matches = { 487 586 DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"), 488 587 }, 489 - _CBDD(acer_c720), 588 + .driver_data = (void *)&acer_c720, 490 589 }, 491 590 { 492 591 .ident = "HP Pavilion 14 Chromebook", 493 592 .matches = { 494 593 DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"), 495 594 }, 496 - _CBDD(hp_pavilion_14_chromebook), 595 + .driver_data = (void *)&hp_pavilion_14_chromebook, 497 596 }, 498 597 { 499 598 .ident = "Cr-48", 500 599 .matches = { 501 600 DMI_MATCH(DMI_PRODUCT_NAME, "Mario"), 502 601 }, 503 - _CBDD(cr48), 602 + .driver_data = (void *)&cr48, 504 603 }, 505 604 { } 506 605 }; 507 606 MODULE_DEVICE_TABLE(dmi, chromeos_laptop_dmi_table); 508 607 509 - static struct platform_device *cros_platform_device; 608 + static int __init chromeos_laptop_scan_adapter(struct device *dev, void *data) 609 + { 610 + struct i2c_adapter *adapter; 510 611 511 - static struct platform_driver cros_platform_driver = { 512 - .driver = { 513 - .name = "chromeos_laptop", 514 - }, 515 - .probe = chromeos_laptop_probe, 516 - }; 612 + adapter = i2c_verify_adapter(dev); 613 + if (adapter) 614 + chromeos_laptop_check_adapter(adapter); 615 + 616 + return 0; 617 + } 618 + 619 + static int __init chromeos_laptop_get_irq_from_dmi(const char *dmi_name) 620 + { 621 + const struct dmi_device *dmi_dev; 622 + const struct dmi_dev_onboard *dev_data; 623 + 624 + dmi_dev = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD, dmi_name, NULL); 625 + if (!dmi_dev) { 626 + pr_err("failed to find DMI device '%s'\n", dmi_name); 627 + return -ENOENT; 628 + } 629 + 630 + dev_data = dmi_dev->device_data; 631 + if (!dev_data) { 632 + pr_err("failed to get data from DMI for '%s'\n", dmi_name); 633 + return -EINVAL; 634 + } 635 + 636 + return dev_data->instance; 637 + } 638 + 639 + static int __init chromeos_laptop_setup_irq(struct i2c_peripheral *i2c_dev) 640 + { 641 + int irq; 642 + 643 + if (i2c_dev->dmi_name) { 644 + irq = chromeos_laptop_get_irq_from_dmi(i2c_dev->dmi_name); 645 + if (irq < 0) 646 + return irq; 647 + 648 + i2c_dev->irq_resource = (struct resource) 649 + DEFINE_RES_NAMED(irq, 1, NULL, 650 + IORESOURCE_IRQ | i2c_dev->irqflags); 651 + i2c_dev->board_info.resources = &i2c_dev->irq_resource; 652 + i2c_dev->board_info.num_resources = 1; 653 + } 654 + 655 + return 0; 656 + } 657 + 658 + static struct chromeos_laptop * __init 659 + chromeos_laptop_prepare(const struct chromeos_laptop *src) 660 + { 661 + struct chromeos_laptop *cros_laptop; 662 + struct i2c_peripheral *i2c_dev; 663 + struct i2c_board_info *info; 664 + int error; 665 + int i; 666 + 667 + cros_laptop = kzalloc(sizeof(*cros_laptop), GFP_KERNEL); 668 + if (!cros_laptop) 669 + return ERR_PTR(-ENOMEM); 670 + 671 + cros_laptop->i2c_peripherals = kmemdup(src->i2c_peripherals, 672 + src->num_i2c_peripherals * 673 + sizeof(*src->i2c_peripherals), 674 + GFP_KERNEL); 675 + if (!cros_laptop->i2c_peripherals) { 676 + error = -ENOMEM; 677 + goto err_free_cros_laptop; 678 + } 679 + 680 + cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; 681 + 682 + for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { 683 + i2c_dev = &cros_laptop->i2c_peripherals[i]; 684 + info = &i2c_dev->board_info; 685 + 686 + error = chromeos_laptop_setup_irq(i2c_dev); 687 + if (error) 688 + goto err_destroy_cros_peripherals; 689 + 690 + /* We need to deep-copy properties */ 691 + if (info->properties) { 692 + info->properties = 693 + property_entries_dup(info->properties); 694 + if (IS_ERR(info->properties)) { 695 + error = PTR_ERR(info->properties); 696 + goto err_destroy_cros_peripherals; 697 + } 698 + } 699 + } 700 + 701 + return cros_laptop; 702 + 703 + err_destroy_cros_peripherals: 704 + while (--i >= 0) { 705 + i2c_dev = &cros_laptop->i2c_peripherals[i]; 706 + info = &i2c_dev->board_info; 707 + if (info->properties) 708 + property_entries_free(info->properties); 709 + } 710 + kfree(cros_laptop->i2c_peripherals); 711 + err_free_cros_laptop: 712 + kfree(cros_laptop); 713 + return ERR_PTR(error); 714 + } 715 + 716 + static void chromeos_laptop_destroy(const struct chromeos_laptop *cros_laptop) 717 + { 718 + struct i2c_peripheral *i2c_dev; 719 + struct i2c_board_info *info; 720 + int i; 721 + 722 + for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { 723 + i2c_dev = &cros_laptop->i2c_peripherals[i]; 724 + info = &i2c_dev->board_info; 725 + 726 + if (i2c_dev->client) 727 + i2c_unregister_device(i2c_dev->client); 728 + 729 + if (info->properties) 730 + property_entries_free(info->properties); 731 + } 732 + 733 + kfree(cros_laptop->i2c_peripherals); 734 + kfree(cros_laptop); 735 + } 517 736 518 737 static int __init chromeos_laptop_init(void) 519 738 { 520 - int ret; 739 + const struct dmi_system_id *dmi_id; 740 + int error; 521 741 522 - if (!dmi_check_system(chromeos_laptop_dmi_table)) { 523 - pr_debug("%s unsupported system.\n", __func__); 742 + dmi_id = dmi_first_match(chromeos_laptop_dmi_table); 743 + if (!dmi_id) { 744 + pr_debug("unsupported system\n"); 524 745 return -ENODEV; 525 746 } 526 747 527 - ret = platform_driver_register(&cros_platform_driver); 528 - if (ret) 529 - return ret; 748 + pr_debug("DMI Matched %s\n", dmi_id->ident); 530 749 531 - cros_platform_device = platform_device_alloc("chromeos_laptop", -1); 532 - if (!cros_platform_device) { 533 - ret = -ENOMEM; 534 - goto fail_platform_device1; 750 + cros_laptop = chromeos_laptop_prepare((void *)dmi_id->driver_data); 751 + if (IS_ERR(cros_laptop)) 752 + return PTR_ERR(cros_laptop); 753 + 754 + error = bus_register_notifier(&i2c_bus_type, 755 + &chromeos_laptop_i2c_notifier); 756 + if (error) { 757 + pr_err("failed to register i2c bus notifier: %d\n", error); 758 + chromeos_laptop_destroy(cros_laptop); 759 + return error; 535 760 } 536 761 537 - ret = platform_device_add(cros_platform_device); 538 - if (ret) 539 - goto fail_platform_device2; 762 + /* 763 + * Scan adapters that have been registered before we installed 764 + * the notifier to make sure we do not miss any devices. 765 + */ 766 + i2c_for_each_dev(NULL, chromeos_laptop_scan_adapter); 540 767 541 768 return 0; 542 - 543 - fail_platform_device2: 544 - platform_device_put(cros_platform_device); 545 - fail_platform_device1: 546 - platform_driver_unregister(&cros_platform_driver); 547 - return ret; 548 769 } 549 770 550 771 static void __exit chromeos_laptop_exit(void) 551 772 { 552 - if (als) 553 - i2c_unregister_device(als); 554 - if (tp) 555 - i2c_unregister_device(tp); 556 - if (ts) 557 - i2c_unregister_device(ts); 558 - 559 - platform_device_unregister(cros_platform_device); 560 - platform_driver_unregister(&cros_platform_driver); 773 + bus_unregister_notifier(&i2c_bus_type, &chromeos_laptop_i2c_notifier); 774 + chromeos_laptop_destroy(cros_laptop); 561 775 } 562 776 563 777 module_init(chromeos_laptop_init);
+74 -2
drivers/platform/chrome/cros_ec_debugfs.c
··· 211 211 return 0; 212 212 } 213 213 214 + static ssize_t cros_ec_pdinfo_read(struct file *file, 215 + char __user *user_buf, 216 + size_t count, 217 + loff_t *ppos) 218 + { 219 + char read_buf[EC_USB_PD_MAX_PORTS * 40], *p = read_buf; 220 + struct cros_ec_debugfs *debug_info = file->private_data; 221 + struct cros_ec_device *ec_dev = debug_info->ec->ec_dev; 222 + struct { 223 + struct cros_ec_command msg; 224 + union { 225 + struct ec_response_usb_pd_control_v1 resp; 226 + struct ec_params_usb_pd_control params; 227 + }; 228 + } __packed ec_buf; 229 + struct cros_ec_command *msg; 230 + struct ec_response_usb_pd_control_v1 *resp; 231 + struct ec_params_usb_pd_control *params; 232 + int i; 233 + 234 + msg = &ec_buf.msg; 235 + params = (struct ec_params_usb_pd_control *)msg->data; 236 + resp = (struct ec_response_usb_pd_control_v1 *)msg->data; 237 + 238 + msg->command = EC_CMD_USB_PD_CONTROL; 239 + msg->version = 1; 240 + msg->insize = sizeof(*resp); 241 + msg->outsize = sizeof(*params); 242 + 243 + /* 244 + * Read status from all PD ports until failure, typically caused 245 + * by attempting to read status on a port that doesn't exist. 246 + */ 247 + for (i = 0; i < EC_USB_PD_MAX_PORTS; ++i) { 248 + params->port = i; 249 + params->role = 0; 250 + params->mux = 0; 251 + params->swap = 0; 252 + 253 + if (cros_ec_cmd_xfer_status(ec_dev, msg) < 0) 254 + break; 255 + 256 + p += scnprintf(p, sizeof(read_buf) + read_buf - p, 257 + "p%d: %s en:%.2x role:%.2x pol:%.2x\n", i, 258 + resp->state, resp->enabled, resp->role, 259 + resp->polarity); 260 + } 261 + 262 + return simple_read_from_buffer(user_buf, count, ppos, 263 + read_buf, p - read_buf); 264 + } 265 + 214 266 const struct file_operations cros_ec_console_log_fops = { 215 267 .owner = THIS_MODULE, 216 268 .open = cros_ec_console_log_open, ··· 270 218 .llseek = no_llseek, 271 219 .poll = cros_ec_console_log_poll, 272 220 .release = cros_ec_console_log_release, 221 + }; 222 + 223 + const struct file_operations cros_ec_pdinfo_fops = { 224 + .owner = THIS_MODULE, 225 + .open = simple_open, 226 + .read = cros_ec_pdinfo_read, 227 + .llseek = default_llseek, 273 228 }; 274 229 275 230 static int ec_read_version_supported(struct cros_ec_dev *ec) ··· 347 288 init_waitqueue_head(&debug_info->log_wq); 348 289 349 290 if (!debugfs_create_file("console_log", 350 - S_IFREG | S_IRUGO, 291 + S_IFREG | 0444, 351 292 debug_info->dir, 352 293 debug_info, 353 294 &cros_ec_console_log_fops)) ··· 400 341 debug_info->panicinfo_blob.size = ret; 401 342 402 343 if (!debugfs_create_blob("panicinfo", 403 - S_IFREG | S_IRUGO, 344 + S_IFREG | 0444, 404 345 debug_info->dir, 405 346 &debug_info->panicinfo_blob)) { 406 347 ret = -ENOMEM; ··· 412 353 free: 413 354 devm_kfree(debug_info->ec->dev, msg); 414 355 return ret; 356 + } 357 + 358 + static int cros_ec_create_pdinfo(struct cros_ec_debugfs *debug_info) 359 + { 360 + if (!debugfs_create_file("pdinfo", 0444, debug_info->dir, debug_info, 361 + &cros_ec_pdinfo_fops)) 362 + return -ENOMEM; 363 + 364 + return 0; 415 365 } 416 366 417 367 int cros_ec_debugfs_init(struct cros_ec_dev *ec) ··· 444 376 goto remove_debugfs; 445 377 446 378 ret = cros_ec_create_console_log(debug_info); 379 + if (ret) 380 + goto remove_debugfs; 381 + 382 + ret = cros_ec_create_pdinfo(debug_info); 447 383 if (ret) 448 384 goto remove_debugfs; 449 385
+16
drivers/platform/chrome/cros_ec_lpc.c
··· 31 31 #include <linux/module.h> 32 32 #include <linux/platform_device.h> 33 33 #include <linux/printk.h> 34 + #include <linux/suspend.h> 34 35 35 36 #define DRV_NAME "cros_ec_lpcs" 36 37 #define ACPI_DRV_NAME "GOOG0004" ··· 236 235 cros_ec_get_next_event(ec_dev, NULL) > 0) 237 236 blocking_notifier_call_chain(&ec_dev->event_notifier, 0, 238 237 ec_dev); 238 + 239 + if (value == ACPI_NOTIFY_DEVICE_WAKE) 240 + pm_system_wakeup(); 239 241 } 240 242 241 243 static int cros_ec_lpc_probe(struct platform_device *pdev) ··· 343 339 .matches = { 344 340 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 345 341 DMI_MATCH(DMI_BIOS_VERSION, "Google_"), 342 + }, 343 + }, 344 + { 345 + /* 346 + * If the box is running custom coreboot firmware then the 347 + * DMI BIOS version string will not be matched by "Google_", 348 + * but the system vendor string will still be matched by 349 + * "GOOGLE". 350 + */ 351 + .matches = { 352 + DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 353 + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 346 354 }, 347 355 }, 348 356 {
+102 -39
drivers/platform/chrome/cros_ec_sysfs.c
··· 34 34 #include <linux/types.h> 35 35 #include <linux/uaccess.h> 36 36 37 + #define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev) 38 + 37 39 /* Accessor functions */ 38 40 39 - static ssize_t show_ec_reboot(struct device *dev, 40 - struct device_attribute *attr, char *buf) 41 + static ssize_t reboot_show(struct device *dev, 42 + struct device_attribute *attr, char *buf) 41 43 { 42 44 int count = 0; 43 45 ··· 50 48 return count; 51 49 } 52 50 53 - static ssize_t store_ec_reboot(struct device *dev, 54 - struct device_attribute *attr, 55 - const char *buf, size_t count) 51 + static ssize_t reboot_store(struct device *dev, 52 + struct device_attribute *attr, 53 + const char *buf, size_t count) 56 54 { 57 55 static const struct { 58 56 const char * const str; ··· 72 70 int got_cmd = 0, offset = 0; 73 71 int i; 74 72 int ret; 75 - struct cros_ec_dev *ec = container_of(dev, 76 - struct cros_ec_dev, class_dev); 73 + struct cros_ec_dev *ec = to_cros_ec_dev(dev); 77 74 78 75 msg = kmalloc(sizeof(*msg) + sizeof(*param), GFP_KERNEL); 79 76 if (!msg) ··· 115 114 msg->command = EC_CMD_REBOOT_EC + ec->cmd_offset; 116 115 msg->outsize = sizeof(*param); 117 116 msg->insize = 0; 118 - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 119 - if (ret < 0) { 117 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 118 + if (ret < 0) 120 119 count = ret; 121 - goto exit; 122 - } 123 - if (msg->result != EC_RES_SUCCESS) { 124 - dev_dbg(ec->dev, "EC result %d\n", msg->result); 125 - count = -EINVAL; 126 - } 127 120 exit: 128 121 kfree(msg); 129 122 return count; 130 123 } 131 124 132 - static ssize_t show_ec_version(struct device *dev, 133 - struct device_attribute *attr, char *buf) 125 + static ssize_t version_show(struct device *dev, 126 + struct device_attribute *attr, char *buf) 134 127 { 135 128 static const char * const image_names[] = {"unknown", "RO", "RW"}; 136 129 struct ec_response_get_version *r_ver; ··· 133 138 struct cros_ec_command *msg; 134 139 int ret; 135 140 int count = 0; 136 - struct cros_ec_dev *ec = container_of(dev, 137 - struct cros_ec_dev, class_dev); 141 + struct cros_ec_dev *ec = to_cros_ec_dev(dev); 138 142 139 143 msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL); 140 144 if (!msg) ··· 144 150 msg->command = EC_CMD_GET_VERSION + ec->cmd_offset; 145 151 msg->insize = sizeof(*r_ver); 146 152 msg->outsize = 0; 147 - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 153 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 148 154 if (ret < 0) { 149 155 count = ret; 150 156 goto exit; 151 157 } 152 - if (msg->result != EC_RES_SUCCESS) { 153 - count = scnprintf(buf, PAGE_SIZE, 154 - "ERROR: EC returned %d\n", msg->result); 155 - goto exit; 156 - } 157 - 158 158 r_ver = (struct ec_response_get_version *)msg->data; 159 159 /* Strings should be null-terminated, but let's be sure. */ 160 160 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0'; ··· 225 237 return count; 226 238 } 227 239 228 - static ssize_t show_ec_flashinfo(struct device *dev, 229 - struct device_attribute *attr, char *buf) 240 + static ssize_t flashinfo_show(struct device *dev, 241 + struct device_attribute *attr, char *buf) 230 242 { 231 243 struct ec_response_flash_info *resp; 232 244 struct cros_ec_command *msg; 233 245 int ret; 234 - struct cros_ec_dev *ec = container_of(dev, 235 - struct cros_ec_dev, class_dev); 246 + struct cros_ec_dev *ec = to_cros_ec_dev(dev); 236 247 237 248 msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL); 238 249 if (!msg) ··· 242 255 msg->command = EC_CMD_FLASH_INFO + ec->cmd_offset; 243 256 msg->insize = sizeof(*resp); 244 257 msg->outsize = 0; 245 - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 258 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 246 259 if (ret < 0) 247 260 goto exit; 248 - if (msg->result != EC_RES_SUCCESS) { 249 - ret = scnprintf(buf, PAGE_SIZE, 250 - "ERROR: EC returned %d\n", msg->result); 251 - goto exit; 252 - } 253 261 254 262 resp = (struct ec_response_flash_info *)msg->data; 255 263 ··· 258 276 return ret; 259 277 } 260 278 279 + /* Keyboard wake angle control */ 280 + static ssize_t kb_wake_angle_show(struct device *dev, 281 + struct device_attribute *attr, char *buf) 282 + { 283 + struct cros_ec_dev *ec = to_cros_ec_dev(dev); 284 + struct ec_response_motion_sense *resp; 285 + struct ec_params_motion_sense *param; 286 + struct cros_ec_command *msg; 287 + int ret; 288 + 289 + msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL); 290 + if (!msg) 291 + return -ENOMEM; 292 + 293 + param = (struct ec_params_motion_sense *)msg->data; 294 + msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset; 295 + msg->version = 2; 296 + param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE; 297 + param->kb_wake_angle.data = EC_MOTION_SENSE_NO_VALUE; 298 + msg->outsize = sizeof(*param); 299 + msg->insize = sizeof(*resp); 300 + 301 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 302 + if (ret < 0) 303 + goto exit; 304 + 305 + resp = (struct ec_response_motion_sense *)msg->data; 306 + ret = scnprintf(buf, PAGE_SIZE, "%d\n", resp->kb_wake_angle.ret); 307 + exit: 308 + kfree(msg); 309 + return ret; 310 + } 311 + 312 + static ssize_t kb_wake_angle_store(struct device *dev, 313 + struct device_attribute *attr, 314 + const char *buf, size_t count) 315 + { 316 + struct cros_ec_dev *ec = to_cros_ec_dev(dev); 317 + struct ec_params_motion_sense *param; 318 + struct cros_ec_command *msg; 319 + u16 angle; 320 + int ret; 321 + 322 + ret = kstrtou16(buf, 0, &angle); 323 + if (ret) 324 + return ret; 325 + 326 + msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL); 327 + if (!msg) 328 + return -ENOMEM; 329 + 330 + param = (struct ec_params_motion_sense *)msg->data; 331 + msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset; 332 + msg->version = 2; 333 + param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE; 334 + param->kb_wake_angle.data = angle; 335 + msg->outsize = sizeof(*param); 336 + msg->insize = sizeof(struct ec_response_motion_sense); 337 + 338 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 339 + kfree(msg); 340 + if (ret < 0) 341 + return ret; 342 + return count; 343 + } 344 + 261 345 /* Module initialization */ 262 346 263 - static DEVICE_ATTR(reboot, S_IWUSR | S_IRUGO, show_ec_reboot, store_ec_reboot); 264 - static DEVICE_ATTR(version, S_IRUGO, show_ec_version, NULL); 265 - static DEVICE_ATTR(flashinfo, S_IRUGO, show_ec_flashinfo, NULL); 347 + static DEVICE_ATTR_RW(reboot); 348 + static DEVICE_ATTR_RO(version); 349 + static DEVICE_ATTR_RO(flashinfo); 350 + static DEVICE_ATTR_RW(kb_wake_angle); 266 351 267 352 static struct attribute *__ec_attrs[] = { 353 + &dev_attr_kb_wake_angle.attr, 268 354 &dev_attr_reboot.attr, 269 355 &dev_attr_version.attr, 270 356 &dev_attr_flashinfo.attr, 271 357 NULL, 272 358 }; 273 359 360 + static umode_t cros_ec_ctrl_visible(struct kobject *kobj, 361 + struct attribute *a, int n) 362 + { 363 + struct device *dev = container_of(kobj, struct device, kobj); 364 + struct cros_ec_dev *ec = to_cros_ec_dev(dev); 365 + 366 + if (a == &dev_attr_kb_wake_angle.attr && !ec->has_kb_wake_angle) 367 + return 0; 368 + 369 + return a->mode; 370 + } 371 + 274 372 struct attribute_group cros_ec_attr_group = { 275 373 .attrs = __ec_attrs, 374 + .is_visible = cros_ec_ctrl_visible, 276 375 }; 277 376 EXPORT_SYMBOL(cros_ec_attr_group); 278 377
+2
include/linux/mfd/cros_ec.h
··· 183 183 * @ec_dev: cros_ec_device structure to talk to the physical device 184 184 * @dev: pointer to the platform device 185 185 * @debug_info: cros_ec_debugfs structure for debugging information 186 + * @has_kb_wake_angle: true if at least 2 accelerometer are connected to the EC. 186 187 * @cmd_offset: offset to apply for each command. 187 188 */ 188 189 struct cros_ec_dev { ··· 192 191 struct cros_ec_device *ec_dev; 193 192 struct device *dev; 194 193 struct cros_ec_debugfs *debug_info; 194 + bool has_kb_wake_angle; 195 195 u16 cmd_offset; 196 196 u32 features[2]; 197 197 };
+3
include/linux/mfd/cros_ec_commands.h
··· 2948 2948 2949 2949 #define EC_CMD_USB_PD_PORTS 0x102 2950 2950 2951 + /* Maximum number of PD ports on a device, num_ports will be <= this */ 2952 + #define EC_USB_PD_MAX_PORTS 8 2953 + 2951 2954 struct ec_response_usb_pd_ports { 2952 2955 uint8_t num_ports; 2953 2956 } __packed;
-31
include/linux/platform_data/atmel_mxt_ts.h
··· 1 - /* 2 - * Atmel maXTouch Touchscreen driver 3 - * 4 - * Copyright (C) 2010 Samsung Electronics Co.Ltd 5 - * Author: Joonyoung Shim <jy0922.shim@samsung.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - 13 - #ifndef __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H 14 - #define __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H 15 - 16 - #include <linux/types.h> 17 - 18 - enum mxt_suspend_mode { 19 - MXT_SUSPEND_DEEP_SLEEP = 0, 20 - MXT_SUSPEND_T9_CTRL = 1, 21 - }; 22 - 23 - /* The platform data for the Atmel maXTouch touchscreen driver */ 24 - struct mxt_platform_data { 25 - unsigned long irqflags; 26 - u8 t19_num_keys; 27 - const unsigned int *t19_keymap; 28 - enum mxt_suspend_mode suspend_mode; 29 - }; 30 - 31 - #endif /* __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H */