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>
2015-08-04 16:36:29 -07:00
# include <linux/platform_data/atmel_mxt_ts.h>
2013-03-07 19:43:34 -08:00
# 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 " ,
2015-11-03 13:09:00 +02:00
" Synopsys DesignWare I2C adapter " ,
" Synopsys DesignWare I2C adapter " ,
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 ,
2015-08-04 16:36:29 -07:00
. suspend_mode = MXT_SUSPEND_T9_CTRL ,
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 ,
2015-08-04 16:36:29 -07:00
. suspend_mode = MXT_SUSPEND_T9_CTRL ,
2013-03-07 19:43:34 -08:00
} ;
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 ,
2015-04-14 13:50:09 -07:00
const unsigned short * alt_addr_list )
2012-10-25 14:21:21 -07:00
{
const struct dmi_device * dmi_dev ;
const struct dmi_dev_onboard * dev_data ;
struct i2c_adapter * adapter ;
2015-04-14 13:50:09 -07:00
struct i2c_client * client = NULL ;
const unsigned short addr_list [ ] = { info - > addr , I2C_CLIENT_END } ;
2012-10-25 14:21:21 -07:00
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 ;
}
2015-04-14 13:50:09 -07:00
/*
* Add the i2c device . If we can ' t detect it at the primary
* address we scan secondary addresses . In any case the client
* structure gets assigned primary address .
*/
client = i2c_new_probed_device ( adapter , info , addr_list , NULL ) ;
if ( ! client & & alt_addr_list ) {
struct i2c_board_info dummy_info = {
I2C_BOARD_INFO ( " dummy " , info - > addr ) ,
} ;
struct i2c_client * dummy ;
dummy = i2c_new_probed_device ( adapter , & dummy_info ,
alt_addr_list , NULL ) ;
if ( dummy ) {
pr_debug ( " %s %d-%02x is probed at %02x \n " ,
__func__ , bus , info - > addr , dummy - > addr ) ;
i2c_unregister_device ( dummy ) ;
client = i2c_new_device ( adapter , info ) ;
}
}
2012-10-25 14:21:21 -07:00
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
{
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 ,
2015-04-14 13:50:09 -07:00
NULL ) ;
2012-10-25 14:21:21 -07:00
}
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 ,
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 ,
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 " ,
} ,
. 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 " ) ;