| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  chromeos_laptop.c - Driver to instantiate Chromebook i2c/smbus devices. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Author : Benson Leung <bleung@chromium.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Copyright (C) 2012 Google, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  *  it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  *  the Free Software Foundation; either version 2 of the License, or | 
					
						
							|  |  |  |  *  (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  *  GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  *  along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/dmi.h>
 | 
					
						
							|  |  |  | #include <linux/i2c.h>
 | 
					
						
							| 
									
										
										
										
											2013-03-07 19:43:34 -08:00
										 |  |  | #include <linux/i2c/atmel_mxt_ts.h>
 | 
					
						
							|  |  |  | #include <linux/input.h>
 | 
					
						
							|  |  |  | #include <linux/interrupt.h>
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | #include <linux/module.h>
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | #include <linux/platform_device.h>
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:59 -08:00
										 |  |  | #define ATMEL_TP_I2C_ADDR	0x4b
 | 
					
						
							|  |  |  | #define ATMEL_TP_I2C_BL_ADDR	0x25
 | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | #define ATMEL_TS_I2C_ADDR	0x4a
 | 
					
						
							|  |  |  | #define ATMEL_TS_I2C_BL_ADDR	0x26
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | #define CYAPA_TP_I2C_ADDR	0x67
 | 
					
						
							|  |  |  | #define ISL_ALS_I2C_ADDR	0x44
 | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:45 -08:00
										 |  |  | #define TAOS_ALS_I2C_ADDR	0x29
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-15 17:43:11 -07:00
										 |  |  | #define MAX_I2C_DEVICE_DEFERRALS	5
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | static struct i2c_client *als; | 
					
						
							|  |  |  | static struct i2c_client *tp; | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | static struct i2c_client *ts; | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-25 13:10:25 -08:00
										 |  |  | static const char *i2c_adapter_names[] = { | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	"SMBus I801 adapter", | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:55 -08:00
										 |  |  | 	"i915 gmbus vga", | 
					
						
							|  |  |  | 	"i915 gmbus panel", | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 	"i2c-designware-pci", | 
					
						
							|  |  |  | 	"i2c-designware-pci", | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Keep this enum consistent with i2c_adapter_names */ | 
					
						
							|  |  |  | enum i2c_adapter_type { | 
					
						
							|  |  |  | 	I2C_ADAPTER_SMBUS = 0, | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:55 -08:00
										 |  |  | 	I2C_ADAPTER_VGADDC, | 
					
						
							|  |  |  | 	I2C_ADAPTER_PANEL, | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 	I2C_ADAPTER_DESIGNWARE_0, | 
					
						
							|  |  |  | 	I2C_ADAPTER_DESIGNWARE_1, | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-15 17:43:11 -07:00
										 |  |  | enum i2c_peripheral_state { | 
					
						
							|  |  |  | 	UNPROBED = 0, | 
					
						
							|  |  |  | 	PROBED, | 
					
						
							|  |  |  | 	TIMEDOUT, | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | struct i2c_peripheral { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	int (*add)(enum i2c_adapter_type type); | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	enum i2c_adapter_type type; | 
					
						
							| 
									
										
										
										
											2014-07-15 17:43:11 -07:00
										 |  |  | 	enum i2c_peripheral_state state; | 
					
						
							|  |  |  | 	int tries; | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MAX_I2C_PERIPHERALS 3
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct chromeos_laptop { | 
					
						
							|  |  |  | 	struct i2c_peripheral i2c_peripherals[MAX_I2C_PERIPHERALS]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct chromeos_laptop *cros_laptop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct i2c_board_info cyapa_device = { | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), | 
					
						
							|  |  |  | 	.flags		= I2C_CLIENT_WAKE, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct i2c_board_info isl_als_device = { | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct i2c_board_info tsl2583_als_device = { | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:46 -08:00
										 |  |  | 	I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct i2c_board_info tsl2563_als_device = { | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:45 -08:00
										 |  |  | 	I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 23:00:15 -07:00
										 |  |  | static int mxt_t19_keys[] = { | 
					
						
							|  |  |  | 	KEY_RESERVED, | 
					
						
							|  |  |  | 	KEY_RESERVED, | 
					
						
							|  |  |  | 	KEY_RESERVED, | 
					
						
							|  |  |  | 	KEY_RESERVED, | 
					
						
							|  |  |  | 	KEY_RESERVED, | 
					
						
							|  |  |  | 	BTN_LEFT | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-07 19:43:34 -08:00
										 |  |  | static struct mxt_platform_data atmel_224s_tp_platform_data = { | 
					
						
							|  |  |  | 	.irqflags		= IRQF_TRIGGER_FALLING, | 
					
						
							| 
									
										
										
										
											2014-05-18 23:00:15 -07:00
										 |  |  | 	.t19_num_keys		= ARRAY_SIZE(mxt_t19_keys), | 
					
						
							|  |  |  | 	.t19_keymap		= mxt_t19_keys, | 
					
						
							| 
									
										
										
										
											2013-03-07 19:43:34 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct i2c_board_info atmel_224s_tp_device = { | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:59 -08:00
										 |  |  | 	I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR), | 
					
						
							| 
									
										
										
										
											2013-03-07 19:43:34 -08:00
										 |  |  | 	.platform_data = &atmel_224s_tp_platform_data, | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:59 -08:00
										 |  |  | 	.flags		= I2C_CLIENT_WAKE, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-07 19:43:34 -08:00
										 |  |  | static struct mxt_platform_data atmel_1664s_platform_data = { | 
					
						
							|  |  |  | 	.irqflags		= IRQF_TRIGGER_FALLING, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct i2c_board_info atmel_1664s_device = { | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | 	I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR), | 
					
						
							| 
									
										
										
										
											2013-03-07 19:43:34 -08:00
										 |  |  | 	.platform_data = &atmel_1664s_platform_data, | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | 	.flags		= I2C_CLIENT_WAKE, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct i2c_client *__add_probed_i2c_device( | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 		const char *name, | 
					
						
							|  |  |  | 		int bus, | 
					
						
							|  |  |  | 		struct i2c_board_info *info, | 
					
						
							|  |  |  | 		const unsigned short *addrs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const struct dmi_device *dmi_dev; | 
					
						
							|  |  |  | 	const struct dmi_dev_onboard *dev_data; | 
					
						
							|  |  |  | 	struct i2c_adapter *adapter; | 
					
						
							|  |  |  | 	struct i2c_client *client; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (bus < 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * If a name is specified, look for irq platform information stashed | 
					
						
							|  |  |  | 	 * in DMI_DEV_TYPE_DEV_ONBOARD by the Chrome OS custom system firmware. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (name) { | 
					
						
							|  |  |  | 		dmi_dev = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD, name, NULL); | 
					
						
							|  |  |  | 		if (!dmi_dev) { | 
					
						
							|  |  |  | 			pr_err("%s failed to dmi find device %s.\n", | 
					
						
							|  |  |  | 			       __func__, | 
					
						
							|  |  |  | 			       name); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		dev_data = (struct dmi_dev_onboard *)dmi_dev->device_data; | 
					
						
							|  |  |  | 		if (!dev_data) { | 
					
						
							|  |  |  | 			pr_err("%s failed to get data from dmi for %s.\n", | 
					
						
							|  |  |  | 			       __func__, name); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		info->irq = dev_data->instance; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	adapter = i2c_get_adapter(bus); | 
					
						
							|  |  |  | 	if (!adapter) { | 
					
						
							|  |  |  | 		pr_err("%s failed to get i2c adapter %d.\n", __func__, bus); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* add the i2c device */ | 
					
						
							|  |  |  | 	client = i2c_new_probed_device(adapter, info, addrs, NULL); | 
					
						
							|  |  |  | 	if (!client) | 
					
						
							| 
									
										
										
										
											2014-07-15 17:43:11 -07:00
										 |  |  | 		pr_notice("%s failed to register device %d-%02x\n", | 
					
						
							|  |  |  | 			  __func__, bus, info->addr); | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		pr_debug("%s added i2c device %d-%02x\n", | 
					
						
							|  |  |  | 			 __func__, bus, info->addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	i2c_put_adapter(adapter); | 
					
						
							|  |  |  | 	return client; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | struct i2c_lookup { | 
					
						
							|  |  |  | 	const char *name; | 
					
						
							|  |  |  | 	int instance; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int __find_i2c_adap(struct device *dev, void *data) | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 	struct i2c_lookup *lookup = data; | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	static const char *prefix = "i2c-"; | 
					
						
							|  |  |  | 	struct i2c_adapter *adapter; | 
					
						
							| 
									
										
										
										
											2014-05-29 20:45:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	adapter = to_i2c_adapter(dev); | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 	if (strncmp(adapter->name, lookup->name, strlen(lookup->name)) == 0 && | 
					
						
							|  |  |  | 	    lookup->n++ == lookup->instance) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int find_i2c_adapter_num(enum i2c_adapter_type type) | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct device *dev = NULL; | 
					
						
							|  |  |  | 	struct i2c_adapter *adapter; | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 	struct i2c_lookup lookup; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset(&lookup, 0, sizeof(lookup)); | 
					
						
							|  |  |  | 	lookup.name = i2c_adapter_names[type]; | 
					
						
							|  |  |  | 	lookup.instance = (type == I2C_ADAPTER_DESIGNWARE_1) ? 1 : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	/* find the adapter by name */ | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 	dev = bus_find_device(&i2c_bus_type, NULL, &lookup, __find_i2c_adap); | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	if (!dev) { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 		/* Adapters may appear later. Deferred probing will retry */ | 
					
						
							|  |  |  | 		pr_notice("%s: i2c adapter %s not found on system.\n", __func__, | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 			  lookup.name); | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 		return -ENODEV; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	adapter = to_i2c_adapter(dev); | 
					
						
							|  |  |  | 	return adapter->nr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:58 -08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Takes a list of addresses in addrs as such : | 
					
						
							|  |  |  |  * { addr1, ... , addrn, I2C_CLIENT_END }; | 
					
						
							|  |  |  |  * add_probed_i2c_device will use i2c_new_probed_device | 
					
						
							|  |  |  |  * and probe for devices at all of the addresses listed. | 
					
						
							|  |  |  |  * Returns NULL if no devices found. | 
					
						
							|  |  |  |  * See Documentation/i2c/instantiating-devices for more information. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct i2c_client *add_probed_i2c_device( | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:58 -08:00
										 |  |  | 		const char *name, | 
					
						
							|  |  |  | 		enum i2c_adapter_type type, | 
					
						
							|  |  |  | 		struct i2c_board_info *info, | 
					
						
							|  |  |  | 		const unsigned short *addrs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return __add_probed_i2c_device(name, | 
					
						
							|  |  |  | 				       find_i2c_adapter_num(type), | 
					
						
							|  |  |  | 				       info, | 
					
						
							|  |  |  | 				       addrs); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Probes for a device at a single address, the one provided by | 
					
						
							|  |  |  |  * info->addr. | 
					
						
							|  |  |  |  * Returns NULL if no device found. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct i2c_client *add_i2c_device(const char *name, | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:56 -08:00
										 |  |  | 						enum i2c_adapter_type type, | 
					
						
							|  |  |  | 						struct i2c_board_info *info) | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END }; | 
					
						
							| 
									
										
										
										
											2014-05-29 20:45:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	return __add_probed_i2c_device(name, | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:56 -08:00
										 |  |  | 				       find_i2c_adapter_num(type), | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 				       info, | 
					
						
							|  |  |  | 				       addr_list); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int setup_cyapa_tp(enum i2c_adapter_type type) | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	if (tp) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	/* add cyapa touchpad */ | 
					
						
							|  |  |  | 	tp = add_i2c_device("trackpad", type, &cyapa_device); | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	return (!tp) ? -EAGAIN : 0; | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int setup_atmel_224s_tp(enum i2c_adapter_type type) | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:59 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	const unsigned short addr_list[] = { ATMEL_TP_I2C_BL_ADDR, | 
					
						
							|  |  |  | 					     ATMEL_TP_I2C_ADDR, | 
					
						
							|  |  |  | 					     I2C_CLIENT_END }; | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	if (tp) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	/* add atmel mxt touchpad */ | 
					
						
							|  |  |  | 	tp = add_probed_i2c_device("trackpad", type, | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:59 -08:00
										 |  |  | 				   &atmel_224s_tp_device, addr_list); | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	return (!tp) ? -EAGAIN : 0; | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:59 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int setup_atmel_1664s_ts(enum i2c_adapter_type type) | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	const unsigned short addr_list[] = { ATMEL_TS_I2C_BL_ADDR, | 
					
						
							|  |  |  | 					     ATMEL_TS_I2C_ADDR, | 
					
						
							|  |  |  | 					     I2C_CLIENT_END }; | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	if (ts) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	/* add atmel mxt touch device */ | 
					
						
							|  |  |  | 	ts = add_probed_i2c_device("touchscreen", type, | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | 				   &atmel_1664s_device, addr_list); | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	return (!ts) ? -EAGAIN : 0; | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int setup_isl29018_als(enum i2c_adapter_type type) | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	if (als) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	/* add isl29018 light sensor */ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	als = add_i2c_device("lightsensor", type, &isl_als_device); | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	return (!als) ? -EAGAIN : 0; | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int setup_tsl2583_als(enum i2c_adapter_type type) | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:57 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	if (als) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	/* add tsl2583 light sensor */ | 
					
						
							|  |  |  | 	als = add_i2c_device(NULL, type, &tsl2583_als_device); | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	return (!als) ? -EAGAIN : 0; | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:57 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int setup_tsl2563_als(enum i2c_adapter_type type) | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:46 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	if (als) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	/* add tsl2563 light sensor */ | 
					
						
							|  |  |  | 	als = add_i2c_device(NULL, type, &tsl2563_als_device); | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	return (!als) ? -EAGAIN : 0; | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:46 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static int __init chromeos_laptop_dmi_matched(const struct dmi_system_id *id) | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:45 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	cros_laptop = (void *)id->driver_data; | 
					
						
							|  |  |  | 	pr_debug("DMI Matched %s.\n", id->ident); | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	/* Indicate to dmi_scan that processing is done. */ | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int chromeos_laptop_probe(struct platform_device *pdev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	int ret = 0; | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < MAX_I2C_PERIPHERALS; i++) { | 
					
						
							|  |  |  | 		struct i2c_peripheral *i2c_dev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		i2c_dev = &cros_laptop->i2c_peripherals[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* No more peripherals. */ | 
					
						
							|  |  |  | 		if (i2c_dev->add == NULL) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-15 17:43:11 -07:00
										 |  |  | 		if (i2c_dev->state == TIMEDOUT || i2c_dev->state == PROBED) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Check that the i2c adapter is present. | 
					
						
							|  |  |  | 		 * -EPROBE_DEFER if missing as the adapter may appear much | 
					
						
							|  |  |  | 		 * later. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		if (find_i2c_adapter_num(i2c_dev->type) == -ENODEV) { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 			ret = -EPROBE_DEFER; | 
					
						
							| 
									
										
										
										
											2014-07-15 17:43:11 -07:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Add the device. */ | 
					
						
							|  |  |  | 		if (i2c_dev->add(i2c_dev->type) == -EAGAIN) { | 
					
						
							|  |  |  | 			/*
 | 
					
						
							|  |  |  | 			 * Set -EPROBE_DEFER a limited num of times | 
					
						
							|  |  |  | 			 * if device is not successfully added. | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			if (++i2c_dev->tries < MAX_I2C_DEVICE_DEFERRALS) { | 
					
						
							|  |  |  | 				ret = -EPROBE_DEFER; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				/* Ran out of tries. */ | 
					
						
							|  |  |  | 				pr_notice("%s: Ran out of tries for device.\n", | 
					
						
							|  |  |  | 					  __func__); | 
					
						
							|  |  |  | 				i2c_dev->state = TIMEDOUT; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			i2c_dev->state = PROBED; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:45 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct chromeos_laptop samsung_series_5_550 = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Touchpad. */ | 
					
						
							|  |  |  | 		{ .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, | 
					
						
							|  |  |  | 		/* Light Sensor. */ | 
					
						
							|  |  |  | 		{ .add = setup_isl29018_als, I2C_ADAPTER_SMBUS }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct chromeos_laptop samsung_series_5 = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Light Sensor. */ | 
					
						
							|  |  |  | 		{ .add = setup_tsl2583_als, I2C_ADAPTER_SMBUS }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct chromeos_laptop chromebook_pixel = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Touch Screen. */ | 
					
						
							|  |  |  | 		{ .add = setup_atmel_1664s_ts, I2C_ADAPTER_PANEL }, | 
					
						
							|  |  |  | 		/* Touchpad. */ | 
					
						
							|  |  |  | 		{ .add = setup_atmel_224s_tp, I2C_ADAPTER_VGADDC }, | 
					
						
							|  |  |  | 		/* Light Sensor. */ | 
					
						
							|  |  |  | 		{ .add = setup_isl29018_als, I2C_ADAPTER_PANEL }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:01 -07:00
										 |  |  | static struct chromeos_laptop hp_chromebook_14 = { | 
					
						
							|  |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Touchpad. */ | 
					
						
							|  |  |  | 		{ .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:02 -07:00
										 |  |  | static struct chromeos_laptop dell_chromebook_11 = { | 
					
						
							|  |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Touchpad. */ | 
					
						
							|  |  |  | 		{ .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:03 -07:00
										 |  |  | static struct chromeos_laptop toshiba_cb35 = { | 
					
						
							|  |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Touchpad. */ | 
					
						
							|  |  |  | 		{ .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct chromeos_laptop acer_c7_chromebook = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Touchpad. */ | 
					
						
							|  |  |  | 		{ .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct chromeos_laptop acer_ac700 = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Light Sensor. */ | 
					
						
							|  |  |  | 		{ .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | static struct chromeos_laptop acer_c720 = { | 
					
						
							|  |  |  | 	.i2c_peripherals = { | 
					
						
							| 
									
										
										
										
											2014-07-15 20:00:54 -04:00
										 |  |  | 		/* Touchscreen. */ | 
					
						
							|  |  |  | 		{ .add = setup_atmel_1664s_ts, I2C_ADAPTER_DESIGNWARE_1 }, | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 		/* Touchpad. */ | 
					
						
							|  |  |  | 		{ .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, | 
					
						
							|  |  |  | 		/* Light Sensor. */ | 
					
						
							|  |  |  | 		{ .add = setup_isl29018_als, I2C_ADAPTER_DESIGNWARE_1 }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct chromeos_laptop hp_pavilion_14_chromebook = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Touchpad. */ | 
					
						
							|  |  |  | 		{ .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct chromeos_laptop cr48 = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	.i2c_peripherals = { | 
					
						
							|  |  |  | 		/* Light Sensor. */ | 
					
						
							|  |  |  | 		{ .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS }, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define _CBDD(board_) \
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	.callback = chromeos_laptop_dmi_matched, \ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 	.driver_data = (void *)&board_ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:26 -07:00
										 |  |  | static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = { | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		.ident = "Samsung Series 5 550", | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 		.matches = { | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"), | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		_CBDD(samsung_series_5_550), | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:59 -08:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		.ident = "Samsung Series 5", | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 		.matches = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Alex"), | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		_CBDD(samsung_series_5), | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:57 -08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		.ident = "Chromebook Pixel", | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:57 -08:00
										 |  |  | 		.matches = { | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Link"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		_CBDD(chromebook_pixel), | 
					
						
							| 
									
										
										
										
											2013-02-21 12:14:57 -08:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:02 -07:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		.ident = "Wolf", | 
					
						
							|  |  |  | 		.matches = { | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Wolf"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		_CBDD(dell_chromebook_11), | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:01 -07:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		.ident = "HP Chromebook 14", | 
					
						
							|  |  |  | 		.matches = { | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Falco"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		_CBDD(hp_chromebook_14), | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:03 -07:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		.ident = "Toshiba CB35", | 
					
						
							|  |  |  | 		.matches = { | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Leon"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		_CBDD(toshiba_cb35), | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:44 -08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		.ident = "Acer C7 Chromebook", | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:44 -08:00
										 |  |  | 		.matches = { | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Parrot"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		_CBDD(acer_c7_chromebook), | 
					
						
							| 
									
										
										
										
											2013-02-10 16:20:17 -08:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		.ident = "Acer AC700", | 
					
						
							| 
									
										
										
										
											2013-02-10 16:20:17 -08:00
										 |  |  | 		.matches = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), | 
					
						
							| 
									
										
										
										
											2013-02-10 16:20:17 -08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		_CBDD(acer_ac700), | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:44 -08:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-06-17 14:02:00 -07:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		.ident = "Acer C720", | 
					
						
							|  |  |  | 		.matches = { | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		_CBDD(acer_c720), | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:46 -08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		.ident = "HP Pavilion 14 Chromebook", | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:46 -08:00
										 |  |  | 		.matches = { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"), | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:46 -08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		_CBDD(hp_pavilion_14_chromebook), | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:46 -08:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:45 -08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		.ident = "Cr-48", | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:45 -08:00
										 |  |  | 		.matches = { | 
					
						
							|  |  |  | 			DMI_MATCH(DMI_PRODUCT_NAME, "Mario"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:24 -07:00
										 |  |  | 		_CBDD(cr48), | 
					
						
							| 
									
										
										
										
											2013-02-01 14:34:45 -08:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	{ } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | MODULE_DEVICE_TABLE(dmi, chromeos_laptop_dmi_table); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | static struct platform_device *cros_platform_device; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct platform_driver cros_platform_driver = { | 
					
						
							|  |  |  | 	.driver = { | 
					
						
							|  |  |  | 		.name = "chromeos_laptop", | 
					
						
							|  |  |  | 		.owner = THIS_MODULE, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	.probe = chromeos_laptop_probe, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | static int __init chromeos_laptop_init(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2014-05-29 20:45:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	if (!dmi_check_system(chromeos_laptop_dmi_table)) { | 
					
						
							|  |  |  | 		pr_debug("%s unsupported system.\n", __func__); | 
					
						
							|  |  |  | 		return -ENODEV; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ret = platform_driver_register(&cros_platform_driver); | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cros_platform_device = platform_device_alloc("chromeos_laptop", -1); | 
					
						
							|  |  |  | 	if (!cros_platform_device) { | 
					
						
							|  |  |  | 		ret = -ENOMEM; | 
					
						
							|  |  |  | 		goto fail_platform_device1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = platform_device_add(cros_platform_device); | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto fail_platform_device2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2013-10-20 20:58:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail_platform_device2: | 
					
						
							|  |  |  | 	platform_device_put(cros_platform_device); | 
					
						
							|  |  |  | fail_platform_device1: | 
					
						
							|  |  |  | 	platform_driver_unregister(&cros_platform_driver); | 
					
						
							|  |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void __exit chromeos_laptop_exit(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (als) | 
					
						
							|  |  |  | 		i2c_unregister_device(als); | 
					
						
							|  |  |  | 	if (tp) | 
					
						
							|  |  |  | 		i2c_unregister_device(tp); | 
					
						
							| 
									
										
										
										
											2013-02-21 12:15:00 -08:00
										 |  |  | 	if (ts) | 
					
						
							|  |  |  | 		i2c_unregister_device(ts); | 
					
						
							| 
									
										
										
										
											2013-11-27 11:34:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	platform_device_unregister(cros_platform_device); | 
					
						
							|  |  |  | 	platform_driver_unregister(&cros_platform_driver); | 
					
						
							| 
									
										
										
										
											2012-10-25 14:21:21 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module_init(chromeos_laptop_init); | 
					
						
							|  |  |  | module_exit(chromeos_laptop_exit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MODULE_DESCRIPTION("Chrome OS Laptop driver"); | 
					
						
							|  |  |  | MODULE_AUTHOR("Benson Leung <bleung@chromium.org>"); | 
					
						
							|  |  |  | MODULE_LICENSE("GPL"); |