Changes to chrome-platform for v4.17
Incorporates 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. Includes a series to clean up sysfs and debugfs for cros_ec. Other misc. cleanups. Thanks, Benson -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE6gYDF28Li+nEiKLaHwn1ewov5lgFAlrP2NkACgkQHwn1ewov 5lhd7RAAgueLytizaj9QlWgiq5mqN6OJ9z+QoipmCQlB2oqSAJZhWJ17BT91t+dW 0V/xaV0qJ6k8ttcC2UiDAiyFrLk9T/7tYjcvqsNQPz4zMqRcKO73m92+hBcIWIFV X0DUyNvck1sE0lKgmvuKo+m8Rhtrf13gkYVeYp3RV21PiEaUmhn8hr88L83arnPu SHsk/PUS4cQo/Pwfgxc7Zh6jXDMByCw3oIBdmxbbNtZOnWBatmO2N20rn2yQC77d I/+n6zHgkTpZ2TpjtzYRxb9iW2NdgDwEDaJt/r57Nk+z0XEgYfvS8U+R/vYC4Lb8 C6sIgAGP5gCv9wh9UJOC1+XlZRGeKHSLZkQRHqESV7K38aOLX7lQopwGR5USYimY KtUIknRJSZD/jiGyH8NW94u6RlxeoqLWP7GKERm8gGhOkTAqjvFfD5uBLZbEl9Ub Bk9HPIZ/Nq1mg0srGQjSuhgRFoub1MWriD6xthy9PfV0i72pxtRfIZuvhieCBvQ/ Bi3HW05uMfXasuGOjsDJbCbTiKmISMtBC7B1XXE0ioUcZE2bnFyYBmL92E+Vck6q mxFmmdwHmbDrShaEmzWTnXRCA/06QABxWZK0S2IZWu/qy8+UP4OwxFFNvC+6vKNN utUBvmCYjt46CZ0q6JD9eeQ8E7lf0HMJh4DMManrB2fa7BAhLQQ= =mDkk -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
f6811370b9
@ -2426,7 +2426,6 @@ T: git git://github.com/ndyer/linux.git
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
|
F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
|
||||||
F: drivers/input/touchscreen/atmel_mxt_ts.c
|
F: drivers/input/touchscreen/atmel_mxt_ts.c
|
||||||
F: include/linux/platform_data/atmel_mxt_ts.h
|
|
||||||
|
|
||||||
ATMEL SAMA5D2 ADC DRIVER
|
ATMEL SAMA5D2 ADC DRIVER
|
||||||
M: Ludovic Desroches <ludovic.desroches@microchip.com>
|
M: Ludovic Desroches <ludovic.desroches@microchip.com>
|
||||||
|
@ -23,12 +23,13 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/platform_data/atmel_mxt_ts.h>
|
|
||||||
#include <linux/input/mt.h>
|
#include <linux/input/mt.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/property.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/gpio/consumer.h>
|
#include <linux/gpio/consumer.h>
|
||||||
|
#include <linux/property.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
#include <media/v4l2-device.h>
|
#include <media/v4l2-device.h>
|
||||||
#include <media/v4l2-ioctl.h>
|
#include <media/v4l2-ioctl.h>
|
||||||
@ -268,12 +269,16 @@ static const struct v4l2_file_operations mxt_video_fops = {
|
|||||||
.poll = vb2_fop_poll,
|
.poll = vb2_fop_poll,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum mxt_suspend_mode {
|
||||||
|
MXT_SUSPEND_DEEP_SLEEP = 0,
|
||||||
|
MXT_SUSPEND_T9_CTRL = 1,
|
||||||
|
};
|
||||||
|
|
||||||
/* Each client has this additional data */
|
/* Each client has this additional data */
|
||||||
struct mxt_data {
|
struct mxt_data {
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct input_dev *input_dev;
|
struct input_dev *input_dev;
|
||||||
char phys[64]; /* device physical location */
|
char phys[64]; /* device physical location */
|
||||||
const struct mxt_platform_data *pdata;
|
|
||||||
struct mxt_object *object_table;
|
struct mxt_object *object_table;
|
||||||
struct mxt_info info;
|
struct mxt_info info;
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
@ -324,6 +329,11 @@ struct mxt_data {
|
|||||||
|
|
||||||
/* for config update handling */
|
/* for config update handling */
|
||||||
struct completion crc_completion;
|
struct completion crc_completion;
|
||||||
|
|
||||||
|
u32 *t19_keymap;
|
||||||
|
unsigned int t19_num_keys;
|
||||||
|
|
||||||
|
enum mxt_suspend_mode suspend_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mxt_vb2_buffer {
|
struct mxt_vb2_buffer {
|
||||||
@ -742,15 +752,14 @@ static int mxt_write_object(struct mxt_data *data,
|
|||||||
static void mxt_input_button(struct mxt_data *data, u8 *message)
|
static void mxt_input_button(struct mxt_data *data, u8 *message)
|
||||||
{
|
{
|
||||||
struct input_dev *input = data->input_dev;
|
struct input_dev *input = data->input_dev;
|
||||||
const struct mxt_platform_data *pdata = data->pdata;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < pdata->t19_num_keys; i++) {
|
for (i = 0; i < data->t19_num_keys; i++) {
|
||||||
if (pdata->t19_keymap[i] == KEY_RESERVED)
|
if (data->t19_keymap[i] == KEY_RESERVED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Active-low switch */
|
/* Active-low switch */
|
||||||
input_report_key(input, pdata->t19_keymap[i],
|
input_report_key(input, data->t19_keymap[i],
|
||||||
!(message[1] & BIT(i)));
|
!(message[1] & BIT(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -758,7 +767,7 @@ static void mxt_input_button(struct mxt_data *data, u8 *message)
|
|||||||
static void mxt_input_sync(struct mxt_data *data)
|
static void mxt_input_sync(struct mxt_data *data)
|
||||||
{
|
{
|
||||||
input_mt_report_pointer_emulation(data->input_dev,
|
input_mt_report_pointer_emulation(data->input_dev,
|
||||||
data->pdata->t19_num_keys);
|
data->t19_num_keys);
|
||||||
input_sync(data->input_dev);
|
input_sync(data->input_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1858,7 +1867,6 @@ static void mxt_input_close(struct input_dev *dev);
|
|||||||
static void mxt_set_up_as_touchpad(struct input_dev *input_dev,
|
static void mxt_set_up_as_touchpad(struct input_dev *input_dev,
|
||||||
struct mxt_data *data)
|
struct mxt_data *data)
|
||||||
{
|
{
|
||||||
const struct mxt_platform_data *pdata = data->pdata;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
input_dev->name = "Atmel maXTouch Touchpad";
|
input_dev->name = "Atmel maXTouch Touchpad";
|
||||||
@ -1872,15 +1880,14 @@ static void mxt_set_up_as_touchpad(struct input_dev *input_dev,
|
|||||||
input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
|
input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
|
||||||
MXT_PIXELS_PER_MM);
|
MXT_PIXELS_PER_MM);
|
||||||
|
|
||||||
for (i = 0; i < pdata->t19_num_keys; i++)
|
for (i = 0; i < data->t19_num_keys; i++)
|
||||||
if (pdata->t19_keymap[i] != KEY_RESERVED)
|
if (data->t19_keymap[i] != KEY_RESERVED)
|
||||||
input_set_capability(input_dev, EV_KEY,
|
input_set_capability(input_dev, EV_KEY,
|
||||||
pdata->t19_keymap[i]);
|
data->t19_keymap[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mxt_initialize_input_device(struct mxt_data *data)
|
static int mxt_initialize_input_device(struct mxt_data *data)
|
||||||
{
|
{
|
||||||
const struct mxt_platform_data *pdata = data->pdata;
|
|
||||||
struct device *dev = &data->client->dev;
|
struct device *dev = &data->client->dev;
|
||||||
struct input_dev *input_dev;
|
struct input_dev *input_dev;
|
||||||
int error;
|
int error;
|
||||||
@ -1946,7 +1953,7 @@ static int mxt_initialize_input_device(struct mxt_data *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If device has buttons we assume it is a touchpad */
|
/* If device has buttons we assume it is a touchpad */
|
||||||
if (pdata->t19_num_keys) {
|
if (data->t19_num_keys) {
|
||||||
mxt_set_up_as_touchpad(input_dev, data);
|
mxt_set_up_as_touchpad(input_dev, data);
|
||||||
mt_flags |= INPUT_MT_POINTER;
|
mt_flags |= INPUT_MT_POINTER;
|
||||||
} else {
|
} else {
|
||||||
@ -2868,7 +2875,7 @@ static const struct attribute_group mxt_attr_group = {
|
|||||||
|
|
||||||
static void mxt_start(struct mxt_data *data)
|
static void mxt_start(struct mxt_data *data)
|
||||||
{
|
{
|
||||||
switch (data->pdata->suspend_mode) {
|
switch (data->suspend_mode) {
|
||||||
case MXT_SUSPEND_T9_CTRL:
|
case MXT_SUSPEND_T9_CTRL:
|
||||||
mxt_soft_reset(data);
|
mxt_soft_reset(data);
|
||||||
|
|
||||||
@ -2886,12 +2893,11 @@ static void mxt_start(struct mxt_data *data)
|
|||||||
mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
|
mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mxt_stop(struct mxt_data *data)
|
static void mxt_stop(struct mxt_data *data)
|
||||||
{
|
{
|
||||||
switch (data->pdata->suspend_mode) {
|
switch (data->suspend_mode) {
|
||||||
case MXT_SUSPEND_T9_CTRL:
|
case MXT_SUSPEND_T9_CTRL:
|
||||||
/* Touch disable */
|
/* Touch disable */
|
||||||
mxt_write_object(data,
|
mxt_write_object(data,
|
||||||
@ -2921,55 +2927,49 @@ static void mxt_input_close(struct input_dev *dev)
|
|||||||
mxt_stop(data);
|
mxt_stop(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_OF
|
static int mxt_parse_device_properties(struct mxt_data *data)
|
||||||
static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
|
|
||||||
{
|
{
|
||||||
struct mxt_platform_data *pdata;
|
static const char keymap_property[] = "linux,gpio-keymap";
|
||||||
struct device_node *np = client->dev.of_node;
|
struct device *dev = &data->client->dev;
|
||||||
u32 *keymap;
|
u32 *keymap;
|
||||||
int proplen, ret;
|
int n_keys;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!np)
|
if (device_property_present(dev, keymap_property)) {
|
||||||
return ERR_PTR(-ENOENT);
|
n_keys = device_property_read_u32_array(dev, keymap_property,
|
||||||
|
NULL, 0);
|
||||||
|
if (n_keys <= 0) {
|
||||||
|
error = n_keys < 0 ? n_keys : -EINVAL;
|
||||||
|
dev_err(dev, "invalid/malformed '%s' property: %d\n",
|
||||||
|
keymap_property, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
|
keymap = devm_kmalloc_array(dev, n_keys, sizeof(*keymap),
|
||||||
if (!pdata)
|
GFP_KERNEL);
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
if (of_find_property(np, "linux,gpio-keymap", &proplen)) {
|
|
||||||
pdata->t19_num_keys = proplen / sizeof(u32);
|
|
||||||
|
|
||||||
keymap = devm_kzalloc(&client->dev,
|
|
||||||
pdata->t19_num_keys * sizeof(keymap[0]),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!keymap)
|
if (!keymap)
|
||||||
return ERR_PTR(-ENOMEM);
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = of_property_read_u32_array(np, "linux,gpio-keymap",
|
error = device_property_read_u32_array(dev, keymap_property,
|
||||||
keymap, pdata->t19_num_keys);
|
keymap, n_keys);
|
||||||
if (ret)
|
if (error) {
|
||||||
dev_warn(&client->dev,
|
dev_err(dev, "failed to parse '%s' property: %d\n",
|
||||||
"Couldn't read linux,gpio-keymap: %d\n", ret);
|
keymap_property, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
pdata->t19_keymap = keymap;
|
data->t19_keymap = keymap;
|
||||||
|
data->t19_num_keys = n_keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdata->suspend_mode = MXT_SUSPEND_DEEP_SLEEP;
|
return 0;
|
||||||
|
|
||||||
return pdata;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
|
|
||||||
{
|
|
||||||
return ERR_PTR(-ENOENT);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
|
|
||||||
struct mxt_acpi_platform_data {
|
struct mxt_acpi_platform_data {
|
||||||
const char *hid;
|
const char *hid;
|
||||||
struct mxt_platform_data pdata;
|
const struct property_entry *props;
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int samus_touchpad_buttons[] = {
|
static unsigned int samus_touchpad_buttons[] = {
|
||||||
@ -2979,14 +2979,16 @@ static unsigned int samus_touchpad_buttons[] = {
|
|||||||
BTN_LEFT
|
BTN_LEFT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct property_entry samus_touchpad_props[] = {
|
||||||
|
PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", samus_touchpad_buttons),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
static struct mxt_acpi_platform_data samus_platform_data[] = {
|
static struct mxt_acpi_platform_data samus_platform_data[] = {
|
||||||
{
|
{
|
||||||
/* Touchpad */
|
/* Touchpad */
|
||||||
.hid = "ATML0000",
|
.hid = "ATML0000",
|
||||||
.pdata = {
|
.props = samus_touchpad_props,
|
||||||
.t19_num_keys = ARRAY_SIZE(samus_touchpad_buttons),
|
|
||||||
.t19_keymap = samus_touchpad_buttons,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* Touchscreen */
|
/* Touchscreen */
|
||||||
@ -3004,14 +3006,16 @@ static unsigned int chromebook_tp_buttons[] = {
|
|||||||
BTN_LEFT
|
BTN_LEFT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct property_entry chromebook_tp_props[] = {
|
||||||
|
PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", chromebook_tp_buttons),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
static struct mxt_acpi_platform_data chromebook_platform_data[] = {
|
static struct mxt_acpi_platform_data chromebook_platform_data[] = {
|
||||||
{
|
{
|
||||||
/* Touchpad */
|
/* Touchpad */
|
||||||
.hid = "ATML0000",
|
.hid = "ATML0000",
|
||||||
.pdata = {
|
.props = chromebook_tp_props,
|
||||||
.t19_num_keys = ARRAY_SIZE(chromebook_tp_buttons),
|
|
||||||
.t19_keymap = chromebook_tp_buttons,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* Touchscreen */
|
/* Touchscreen */
|
||||||
@ -3041,12 +3045,73 @@ static const struct dmi_system_id mxt_dmi_table[] = {
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client *client)
|
static int mxt_prepare_acpi_properties(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct acpi_device *adev;
|
struct acpi_device *adev;
|
||||||
const struct dmi_system_id *system_id;
|
const struct dmi_system_id *system_id;
|
||||||
const struct mxt_acpi_platform_data *acpi_pdata;
|
const struct mxt_acpi_platform_data *acpi_pdata;
|
||||||
|
|
||||||
|
adev = ACPI_COMPANION(&client->dev);
|
||||||
|
if (!adev)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
system_id = dmi_first_match(mxt_dmi_table);
|
||||||
|
if (!system_id)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
acpi_pdata = system_id->driver_data;
|
||||||
|
if (!acpi_pdata)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
while (acpi_pdata->hid) {
|
||||||
|
if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid)) {
|
||||||
|
/*
|
||||||
|
* Remove previously installed properties if we
|
||||||
|
* are probing this device not for the very first
|
||||||
|
* time.
|
||||||
|
*/
|
||||||
|
device_remove_properties(&client->dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now install the platform-specific properties
|
||||||
|
* that are missing from ACPI.
|
||||||
|
*/
|
||||||
|
device_add_properties(&client->dev, acpi_pdata->props);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_pdata++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int mxt_prepare_acpi_properties(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct dmi_system_id chromebook_T9_suspend_dmi[] = {
|
||||||
|
{
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Link"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
struct mxt_data *data;
|
||||||
|
int error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ignore ACPI devices representing bootloader mode.
|
* Ignore ACPI devices representing bootloader mode.
|
||||||
*
|
*
|
||||||
@ -3057,67 +3122,8 @@ static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client *client)
|
|||||||
* application mode addresses were all above 0x40, so we'll use it
|
* application mode addresses were all above 0x40, so we'll use it
|
||||||
* as a threshold.
|
* as a threshold.
|
||||||
*/
|
*/
|
||||||
if (client->addr < 0x40)
|
if (ACPI_COMPANION(&client->dev) && client->addr < 0x40)
|
||||||
return ERR_PTR(-ENXIO);
|
return -ENXIO;
|
||||||
|
|
||||||
adev = ACPI_COMPANION(&client->dev);
|
|
||||||
if (!adev)
|
|
||||||
return ERR_PTR(-ENOENT);
|
|
||||||
|
|
||||||
system_id = dmi_first_match(mxt_dmi_table);
|
|
||||||
if (!system_id)
|
|
||||||
return ERR_PTR(-ENOENT);
|
|
||||||
|
|
||||||
acpi_pdata = system_id->driver_data;
|
|
||||||
if (!acpi_pdata)
|
|
||||||
return ERR_PTR(-ENOENT);
|
|
||||||
|
|
||||||
while (acpi_pdata->hid) {
|
|
||||||
if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid))
|
|
||||||
return &acpi_pdata->pdata;
|
|
||||||
|
|
||||||
acpi_pdata++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERR_PTR(-ENOENT);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client *client)
|
|
||||||
{
|
|
||||||
return ERR_PTR(-ENOENT);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const struct mxt_platform_data *
|
|
||||||
mxt_get_platform_data(struct i2c_client *client)
|
|
||||||
{
|
|
||||||
const struct mxt_platform_data *pdata;
|
|
||||||
|
|
||||||
pdata = dev_get_platdata(&client->dev);
|
|
||||||
if (pdata)
|
|
||||||
return pdata;
|
|
||||||
|
|
||||||
pdata = mxt_parse_dt(client);
|
|
||||||
if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT)
|
|
||||||
return pdata;
|
|
||||||
|
|
||||||
pdata = mxt_parse_acpi(client);
|
|
||||||
if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT)
|
|
||||||
return pdata;
|
|
||||||
|
|
||||||
dev_err(&client->dev, "No platform data specified\n");
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|
||||||
{
|
|
||||||
struct mxt_data *data;
|
|
||||||
const struct mxt_platform_data *pdata;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
pdata = mxt_get_platform_data(client);
|
|
||||||
if (IS_ERR(pdata))
|
|
||||||
return PTR_ERR(pdata);
|
|
||||||
|
|
||||||
data = devm_kzalloc(&client->dev, sizeof(struct mxt_data), GFP_KERNEL);
|
data = devm_kzalloc(&client->dev, sizeof(struct mxt_data), GFP_KERNEL);
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -3127,7 +3133,6 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||||||
client->adapter->nr, client->addr);
|
client->adapter->nr, client->addr);
|
||||||
|
|
||||||
data->client = client;
|
data->client = client;
|
||||||
data->pdata = pdata;
|
|
||||||
data->irq = client->irq;
|
data->irq = client->irq;
|
||||||
i2c_set_clientdata(client, data);
|
i2c_set_clientdata(client, data);
|
||||||
|
|
||||||
@ -3135,6 +3140,17 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||||||
init_completion(&data->reset_completion);
|
init_completion(&data->reset_completion);
|
||||||
init_completion(&data->crc_completion);
|
init_completion(&data->crc_completion);
|
||||||
|
|
||||||
|
data->suspend_mode = dmi_check_system(chromebook_T9_suspend_dmi) ?
|
||||||
|
MXT_SUSPEND_T9_CTRL : MXT_SUSPEND_DEEP_SLEEP;
|
||||||
|
|
||||||
|
error = mxt_prepare_acpi_properties(client);
|
||||||
|
if (error && error != -ENOENT)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
error = mxt_parse_device_properties(data);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
data->reset_gpio = devm_gpiod_get_optional(&client->dev,
|
data->reset_gpio = devm_gpiod_get_optional(&client->dev,
|
||||||
"reset", GPIOD_OUT_LOW);
|
"reset", GPIOD_OUT_LOW);
|
||||||
if (IS_ERR(data->reset_gpio)) {
|
if (IS_ERR(data->reset_gpio)) {
|
||||||
@ -3144,8 +3160,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
error = devm_request_threaded_irq(&client->dev, client->irq,
|
error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||||
NULL, mxt_interrupt,
|
NULL, mxt_interrupt, IRQF_ONESHOT,
|
||||||
pdata->irqflags | IRQF_ONESHOT,
|
|
||||||
client->name, data);
|
client->name, data);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&client->dev, "Failed to register interrupt\n");
|
dev_err(&client->dev, "Failed to register interrupt\n");
|
||||||
@ -3265,7 +3280,7 @@ MODULE_DEVICE_TABLE(i2c, mxt_id);
|
|||||||
static struct i2c_driver mxt_driver = {
|
static struct i2c_driver mxt_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "atmel_mxt_ts",
|
.name = "atmel_mxt_ts",
|
||||||
.of_match_table = of_match_ptr(mxt_of_match),
|
.of_match_table = mxt_of_match,
|
||||||
.acpi_match_table = ACPI_PTR(mxt_acpi_id),
|
.acpi_match_table = ACPI_PTR(mxt_acpi_id),
|
||||||
.pm = &mxt_pm_ops,
|
.pm = &mxt_pm_ops,
|
||||||
},
|
},
|
||||||
|
@ -305,8 +305,8 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec)
|
|||||||
|
|
||||||
resp = (struct ec_response_motion_sense *)msg->data;
|
resp = (struct ec_response_motion_sense *)msg->data;
|
||||||
sensor_num = resp->dump.sensor_count;
|
sensor_num = resp->dump.sensor_count;
|
||||||
/* Allocate 2 extra sensors in case lid angle or FIFO are needed */
|
/* Allocate 1 extra sensors in FIFO are needed */
|
||||||
sensor_cells = kzalloc(sizeof(struct mfd_cell) * (sensor_num + 2),
|
sensor_cells = kzalloc(sizeof(struct mfd_cell) * (sensor_num + 1),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (sensor_cells == NULL)
|
if (sensor_cells == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
@ -362,16 +362,10 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec)
|
|||||||
sensor_type[resp->info.type]++;
|
sensor_type[resp->info.type]++;
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2) {
|
|
||||||
sensor_platforms[id].sensor_num = sensor_num;
|
|
||||||
|
|
||||||
sensor_cells[id].name = "cros-ec-angle";
|
if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2)
|
||||||
sensor_cells[id].id = 0;
|
ec->has_kb_wake_angle = true;
|
||||||
sensor_cells[id].platform_data = &sensor_platforms[id];
|
|
||||||
sensor_cells[id].pdata_size =
|
|
||||||
sizeof(struct cros_ec_sensor_platform);
|
|
||||||
id++;
|
|
||||||
}
|
|
||||||
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
|
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
|
||||||
sensor_cells[id].name = "cros-ec-ring";
|
sensor_cells[id].name = "cros-ec-ring";
|
||||||
id++;
|
id++;
|
||||||
@ -424,6 +418,14 @@ static int ec_device_probe(struct platform_device *pdev)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check whether this EC is a sensor hub. */
|
||||||
|
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
|
||||||
|
cros_ec_sensors_register(ec);
|
||||||
|
|
||||||
|
/* Take control of the lightbar from the EC. */
|
||||||
|
lb_manual_suspend_ctrl(ec, 1);
|
||||||
|
|
||||||
|
/* We can now add the sysfs class, we know which parameter to show */
|
||||||
retval = cdev_device_add(&ec->cdev, &ec->class_dev);
|
retval = cdev_device_add(&ec->cdev, &ec->class_dev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
dev_err(dev, "cdev_device_add failed => %d\n", retval);
|
dev_err(dev, "cdev_device_add failed => %d\n", retval);
|
||||||
@ -433,13 +435,6 @@ static int ec_device_probe(struct platform_device *pdev)
|
|||||||
if (cros_ec_debugfs_init(ec))
|
if (cros_ec_debugfs_init(ec))
|
||||||
dev_warn(dev, "failed to create debugfs directory\n");
|
dev_warn(dev, "failed to create debugfs directory\n");
|
||||||
|
|
||||||
/* check whether this EC is a sensor hub. */
|
|
||||||
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
|
|
||||||
cros_ec_sensors_register(ec);
|
|
||||||
|
|
||||||
/* Take control of the lightbar from the EC. */
|
|
||||||
lb_manual_suspend_ctrl(ec, 1);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -211,6 +211,58 @@ static int cros_ec_console_log_release(struct inode *inode, struct file *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t cros_ec_pdinfo_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count,
|
||||||
|
loff_t *ppos)
|
||||||
|
{
|
||||||
|
char read_buf[EC_USB_PD_MAX_PORTS * 40], *p = read_buf;
|
||||||
|
struct cros_ec_debugfs *debug_info = file->private_data;
|
||||||
|
struct cros_ec_device *ec_dev = debug_info->ec->ec_dev;
|
||||||
|
struct {
|
||||||
|
struct cros_ec_command msg;
|
||||||
|
union {
|
||||||
|
struct ec_response_usb_pd_control_v1 resp;
|
||||||
|
struct ec_params_usb_pd_control params;
|
||||||
|
};
|
||||||
|
} __packed ec_buf;
|
||||||
|
struct cros_ec_command *msg;
|
||||||
|
struct ec_response_usb_pd_control_v1 *resp;
|
||||||
|
struct ec_params_usb_pd_control *params;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
msg = &ec_buf.msg;
|
||||||
|
params = (struct ec_params_usb_pd_control *)msg->data;
|
||||||
|
resp = (struct ec_response_usb_pd_control_v1 *)msg->data;
|
||||||
|
|
||||||
|
msg->command = EC_CMD_USB_PD_CONTROL;
|
||||||
|
msg->version = 1;
|
||||||
|
msg->insize = sizeof(*resp);
|
||||||
|
msg->outsize = sizeof(*params);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read status from all PD ports until failure, typically caused
|
||||||
|
* by attempting to read status on a port that doesn't exist.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < EC_USB_PD_MAX_PORTS; ++i) {
|
||||||
|
params->port = i;
|
||||||
|
params->role = 0;
|
||||||
|
params->mux = 0;
|
||||||
|
params->swap = 0;
|
||||||
|
|
||||||
|
if (cros_ec_cmd_xfer_status(ec_dev, msg) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
p += scnprintf(p, sizeof(read_buf) + read_buf - p,
|
||||||
|
"p%d: %s en:%.2x role:%.2x pol:%.2x\n", i,
|
||||||
|
resp->state, resp->enabled, resp->role,
|
||||||
|
resp->polarity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
read_buf, p - read_buf);
|
||||||
|
}
|
||||||
|
|
||||||
const struct file_operations cros_ec_console_log_fops = {
|
const struct file_operations cros_ec_console_log_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = cros_ec_console_log_open,
|
.open = cros_ec_console_log_open,
|
||||||
@ -220,6 +272,13 @@ const struct file_operations cros_ec_console_log_fops = {
|
|||||||
.release = cros_ec_console_log_release,
|
.release = cros_ec_console_log_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct file_operations cros_ec_pdinfo_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = simple_open,
|
||||||
|
.read = cros_ec_pdinfo_read,
|
||||||
|
.llseek = default_llseek,
|
||||||
|
};
|
||||||
|
|
||||||
static int ec_read_version_supported(struct cros_ec_dev *ec)
|
static int ec_read_version_supported(struct cros_ec_dev *ec)
|
||||||
{
|
{
|
||||||
struct ec_params_get_cmd_versions_v1 *params;
|
struct ec_params_get_cmd_versions_v1 *params;
|
||||||
@ -288,7 +347,7 @@ static int cros_ec_create_console_log(struct cros_ec_debugfs *debug_info)
|
|||||||
init_waitqueue_head(&debug_info->log_wq);
|
init_waitqueue_head(&debug_info->log_wq);
|
||||||
|
|
||||||
if (!debugfs_create_file("console_log",
|
if (!debugfs_create_file("console_log",
|
||||||
S_IFREG | S_IRUGO,
|
S_IFREG | 0444,
|
||||||
debug_info->dir,
|
debug_info->dir,
|
||||||
debug_info,
|
debug_info,
|
||||||
&cros_ec_console_log_fops))
|
&cros_ec_console_log_fops))
|
||||||
@ -341,7 +400,7 @@ static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info)
|
|||||||
debug_info->panicinfo_blob.size = ret;
|
debug_info->panicinfo_blob.size = ret;
|
||||||
|
|
||||||
if (!debugfs_create_blob("panicinfo",
|
if (!debugfs_create_blob("panicinfo",
|
||||||
S_IFREG | S_IRUGO,
|
S_IFREG | 0444,
|
||||||
debug_info->dir,
|
debug_info->dir,
|
||||||
&debug_info->panicinfo_blob)) {
|
&debug_info->panicinfo_blob)) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
@ -355,6 +414,15 @@ free:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cros_ec_create_pdinfo(struct cros_ec_debugfs *debug_info)
|
||||||
|
{
|
||||||
|
if (!debugfs_create_file("pdinfo", 0444, debug_info->dir, debug_info,
|
||||||
|
&cros_ec_pdinfo_fops))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cros_ec_debugfs_init(struct cros_ec_dev *ec)
|
int cros_ec_debugfs_init(struct cros_ec_dev *ec)
|
||||||
{
|
{
|
||||||
struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev);
|
struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev);
|
||||||
@ -379,6 +447,10 @@ int cros_ec_debugfs_init(struct cros_ec_dev *ec)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto remove_debugfs;
|
goto remove_debugfs;
|
||||||
|
|
||||||
|
ret = cros_ec_create_pdinfo(debug_info);
|
||||||
|
if (ret)
|
||||||
|
goto remove_debugfs;
|
||||||
|
|
||||||
ec->debug_info = debug_info;
|
ec->debug_info = debug_info;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/printk.h>
|
#include <linux/printk.h>
|
||||||
|
#include <linux/suspend.h>
|
||||||
|
|
||||||
#define DRV_NAME "cros_ec_lpcs"
|
#define DRV_NAME "cros_ec_lpcs"
|
||||||
#define ACPI_DRV_NAME "GOOG0004"
|
#define ACPI_DRV_NAME "GOOG0004"
|
||||||
@ -235,6 +236,9 @@ static void cros_ec_lpc_acpi_notify(acpi_handle device, u32 value, void *data)
|
|||||||
cros_ec_get_next_event(ec_dev, NULL) > 0)
|
cros_ec_get_next_event(ec_dev, NULL) > 0)
|
||||||
blocking_notifier_call_chain(&ec_dev->event_notifier, 0,
|
blocking_notifier_call_chain(&ec_dev->event_notifier, 0,
|
||||||
ec_dev);
|
ec_dev);
|
||||||
|
|
||||||
|
if (value == ACPI_NOTIFY_DEVICE_WAKE)
|
||||||
|
pm_system_wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cros_ec_lpc_probe(struct platform_device *pdev)
|
static int cros_ec_lpc_probe(struct platform_device *pdev)
|
||||||
@ -341,6 +345,18 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = {
|
|||||||
DMI_MATCH(DMI_BIOS_VERSION, "Google_"),
|
DMI_MATCH(DMI_BIOS_VERSION, "Google_"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the box is running custom coreboot firmware then the
|
||||||
|
* DMI BIOS version string will not be matched by "Google_",
|
||||||
|
* but the system vendor string will still be matched by
|
||||||
|
* "GOOGLE".
|
||||||
|
*/
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
/* x86-link, the Chromebook Pixel. */
|
/* x86-link, the Chromebook Pixel. */
|
||||||
.matches = {
|
.matches = {
|
||||||
|
@ -34,10 +34,12 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
#define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev)
|
||||||
|
|
||||||
/* Accessor functions */
|
/* Accessor functions */
|
||||||
|
|
||||||
static ssize_t show_ec_reboot(struct device *dev,
|
static ssize_t reboot_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
@ -48,9 +50,9 @@ static ssize_t show_ec_reboot(struct device *dev,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t store_ec_reboot(struct device *dev,
|
static ssize_t reboot_store(struct device *dev,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
static const struct {
|
static const struct {
|
||||||
const char * const str;
|
const char * const str;
|
||||||
@ -70,8 +72,7 @@ static ssize_t store_ec_reboot(struct device *dev,
|
|||||||
int got_cmd = 0, offset = 0;
|
int got_cmd = 0, offset = 0;
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
struct cros_ec_dev *ec = container_of(dev,
|
struct cros_ec_dev *ec = to_cros_ec_dev(dev);
|
||||||
struct cros_ec_dev, class_dev);
|
|
||||||
|
|
||||||
msg = kmalloc(sizeof(*msg) + sizeof(*param), GFP_KERNEL);
|
msg = kmalloc(sizeof(*msg) + sizeof(*param), GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
@ -114,22 +115,16 @@ static ssize_t store_ec_reboot(struct device *dev,
|
|||||||
msg->command = EC_CMD_REBOOT_EC + ec->cmd_offset;
|
msg->command = EC_CMD_REBOOT_EC + ec->cmd_offset;
|
||||||
msg->outsize = sizeof(*param);
|
msg->outsize = sizeof(*param);
|
||||||
msg->insize = 0;
|
msg->insize = 0;
|
||||||
ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
|
ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
count = ret;
|
count = ret;
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (msg->result != EC_RES_SUCCESS) {
|
|
||||||
dev_dbg(ec->dev, "EC result %d\n", msg->result);
|
|
||||||
count = -EINVAL;
|
|
||||||
}
|
|
||||||
exit:
|
exit:
|
||||||
kfree(msg);
|
kfree(msg);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t show_ec_version(struct device *dev,
|
static ssize_t version_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
static const char * const image_names[] = {"unknown", "RO", "RW"};
|
static const char * const image_names[] = {"unknown", "RO", "RW"};
|
||||||
struct ec_response_get_version *r_ver;
|
struct ec_response_get_version *r_ver;
|
||||||
@ -138,8 +133,7 @@ static ssize_t show_ec_version(struct device *dev,
|
|||||||
struct cros_ec_command *msg;
|
struct cros_ec_command *msg;
|
||||||
int ret;
|
int ret;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct cros_ec_dev *ec = container_of(dev,
|
struct cros_ec_dev *ec = to_cros_ec_dev(dev);
|
||||||
struct cros_ec_dev, class_dev);
|
|
||||||
|
|
||||||
msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
|
msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
@ -150,17 +144,11 @@ static ssize_t show_ec_version(struct device *dev,
|
|||||||
msg->command = EC_CMD_GET_VERSION + ec->cmd_offset;
|
msg->command = EC_CMD_GET_VERSION + ec->cmd_offset;
|
||||||
msg->insize = sizeof(*r_ver);
|
msg->insize = sizeof(*r_ver);
|
||||||
msg->outsize = 0;
|
msg->outsize = 0;
|
||||||
ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
|
ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
count = ret;
|
count = ret;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (msg->result != EC_RES_SUCCESS) {
|
|
||||||
count = scnprintf(buf, PAGE_SIZE,
|
|
||||||
"ERROR: EC returned %d\n", msg->result);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_ver = (struct ec_response_get_version *)msg->data;
|
r_ver = (struct ec_response_get_version *)msg->data;
|
||||||
/* Strings should be null-terminated, but let's be sure. */
|
/* Strings should be null-terminated, but let's be sure. */
|
||||||
r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0';
|
r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0';
|
||||||
@ -237,14 +225,13 @@ exit:
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t show_ec_flashinfo(struct device *dev,
|
static ssize_t flashinfo_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct ec_response_flash_info *resp;
|
struct ec_response_flash_info *resp;
|
||||||
struct cros_ec_command *msg;
|
struct cros_ec_command *msg;
|
||||||
int ret;
|
int ret;
|
||||||
struct cros_ec_dev *ec = container_of(dev,
|
struct cros_ec_dev *ec = to_cros_ec_dev(dev);
|
||||||
struct cros_ec_dev, class_dev);
|
|
||||||
|
|
||||||
msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL);
|
msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
@ -255,14 +242,9 @@ static ssize_t show_ec_flashinfo(struct device *dev,
|
|||||||
msg->command = EC_CMD_FLASH_INFO + ec->cmd_offset;
|
msg->command = EC_CMD_FLASH_INFO + ec->cmd_offset;
|
||||||
msg->insize = sizeof(*resp);
|
msg->insize = sizeof(*resp);
|
||||||
msg->outsize = 0;
|
msg->outsize = 0;
|
||||||
ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
|
ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
if (msg->result != EC_RES_SUCCESS) {
|
|
||||||
ret = scnprintf(buf, PAGE_SIZE,
|
|
||||||
"ERROR: EC returned %d\n", msg->result);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
resp = (struct ec_response_flash_info *)msg->data;
|
resp = (struct ec_response_flash_info *)msg->data;
|
||||||
|
|
||||||
@ -276,21 +258,102 @@ exit:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Keyboard wake angle control */
|
||||||
|
static ssize_t kb_wake_angle_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct cros_ec_dev *ec = to_cros_ec_dev(dev);
|
||||||
|
struct ec_response_motion_sense *resp;
|
||||||
|
struct ec_params_motion_sense *param;
|
||||||
|
struct cros_ec_command *msg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
|
||||||
|
if (!msg)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
param = (struct ec_params_motion_sense *)msg->data;
|
||||||
|
msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
|
||||||
|
msg->version = 2;
|
||||||
|
param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE;
|
||||||
|
param->kb_wake_angle.data = EC_MOTION_SENSE_NO_VALUE;
|
||||||
|
msg->outsize = sizeof(*param);
|
||||||
|
msg->insize = sizeof(*resp);
|
||||||
|
|
||||||
|
ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
|
||||||
|
if (ret < 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
resp = (struct ec_response_motion_sense *)msg->data;
|
||||||
|
ret = scnprintf(buf, PAGE_SIZE, "%d\n", resp->kb_wake_angle.ret);
|
||||||
|
exit:
|
||||||
|
kfree(msg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t kb_wake_angle_store(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct cros_ec_dev *ec = to_cros_ec_dev(dev);
|
||||||
|
struct ec_params_motion_sense *param;
|
||||||
|
struct cros_ec_command *msg;
|
||||||
|
u16 angle;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = kstrtou16(buf, 0, &angle);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
|
||||||
|
if (!msg)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
param = (struct ec_params_motion_sense *)msg->data;
|
||||||
|
msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
|
||||||
|
msg->version = 2;
|
||||||
|
param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE;
|
||||||
|
param->kb_wake_angle.data = angle;
|
||||||
|
msg->outsize = sizeof(*param);
|
||||||
|
msg->insize = sizeof(struct ec_response_motion_sense);
|
||||||
|
|
||||||
|
ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
|
||||||
|
kfree(msg);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/* Module initialization */
|
/* Module initialization */
|
||||||
|
|
||||||
static DEVICE_ATTR(reboot, S_IWUSR | S_IRUGO, show_ec_reboot, store_ec_reboot);
|
static DEVICE_ATTR_RW(reboot);
|
||||||
static DEVICE_ATTR(version, S_IRUGO, show_ec_version, NULL);
|
static DEVICE_ATTR_RO(version);
|
||||||
static DEVICE_ATTR(flashinfo, S_IRUGO, show_ec_flashinfo, NULL);
|
static DEVICE_ATTR_RO(flashinfo);
|
||||||
|
static DEVICE_ATTR_RW(kb_wake_angle);
|
||||||
|
|
||||||
static struct attribute *__ec_attrs[] = {
|
static struct attribute *__ec_attrs[] = {
|
||||||
|
&dev_attr_kb_wake_angle.attr,
|
||||||
&dev_attr_reboot.attr,
|
&dev_attr_reboot.attr,
|
||||||
&dev_attr_version.attr,
|
&dev_attr_version.attr,
|
||||||
&dev_attr_flashinfo.attr,
|
&dev_attr_flashinfo.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static umode_t cros_ec_ctrl_visible(struct kobject *kobj,
|
||||||
|
struct attribute *a, int n)
|
||||||
|
{
|
||||||
|
struct device *dev = container_of(kobj, struct device, kobj);
|
||||||
|
struct cros_ec_dev *ec = to_cros_ec_dev(dev);
|
||||||
|
|
||||||
|
if (a == &dev_attr_kb_wake_angle.attr && !ec->has_kb_wake_angle)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return a->mode;
|
||||||
|
}
|
||||||
|
|
||||||
struct attribute_group cros_ec_attr_group = {
|
struct attribute_group cros_ec_attr_group = {
|
||||||
.attrs = __ec_attrs,
|
.attrs = __ec_attrs,
|
||||||
|
.is_visible = cros_ec_ctrl_visible,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL(cros_ec_attr_group);
|
EXPORT_SYMBOL(cros_ec_attr_group);
|
||||||
|
|
||||||
|
@ -183,6 +183,7 @@ struct cros_ec_debugfs;
|
|||||||
* @ec_dev: cros_ec_device structure to talk to the physical device
|
* @ec_dev: cros_ec_device structure to talk to the physical device
|
||||||
* @dev: pointer to the platform device
|
* @dev: pointer to the platform device
|
||||||
* @debug_info: cros_ec_debugfs structure for debugging information
|
* @debug_info: cros_ec_debugfs structure for debugging information
|
||||||
|
* @has_kb_wake_angle: true if at least 2 accelerometer are connected to the EC.
|
||||||
* @cmd_offset: offset to apply for each command.
|
* @cmd_offset: offset to apply for each command.
|
||||||
*/
|
*/
|
||||||
struct cros_ec_dev {
|
struct cros_ec_dev {
|
||||||
@ -191,6 +192,7 @@ struct cros_ec_dev {
|
|||||||
struct cros_ec_device *ec_dev;
|
struct cros_ec_device *ec_dev;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct cros_ec_debugfs *debug_info;
|
struct cros_ec_debugfs *debug_info;
|
||||||
|
bool has_kb_wake_angle;
|
||||||
u16 cmd_offset;
|
u16 cmd_offset;
|
||||||
u32 features[2];
|
u32 features[2];
|
||||||
};
|
};
|
||||||
|
@ -2948,6 +2948,9 @@ struct ec_response_usb_pd_control_v1 {
|
|||||||
|
|
||||||
#define EC_CMD_USB_PD_PORTS 0x102
|
#define EC_CMD_USB_PD_PORTS 0x102
|
||||||
|
|
||||||
|
/* Maximum number of PD ports on a device, num_ports will be <= this */
|
||||||
|
#define EC_USB_PD_MAX_PORTS 8
|
||||||
|
|
||||||
struct ec_response_usb_pd_ports {
|
struct ec_response_usb_pd_ports {
|
||||||
uint8_t num_ports;
|
uint8_t num_ports;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Atmel maXTouch Touchscreen driver
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Samsung Electronics Co.Ltd
|
|
||||||
* Author: Joonyoung Shim <jy0922.shim@samsung.com>
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H
|
|
||||||
#define __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
enum mxt_suspend_mode {
|
|
||||||
MXT_SUSPEND_DEEP_SLEEP = 0,
|
|
||||||
MXT_SUSPEND_T9_CTRL = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The platform data for the Atmel maXTouch touchscreen driver */
|
|
||||||
struct mxt_platform_data {
|
|
||||||
unsigned long irqflags;
|
|
||||||
u8 t19_num_keys;
|
|
||||||
const unsigned int *t19_keymap;
|
|
||||||
enum mxt_suspend_mode suspend_mode;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H */
|
|
Loading…
Reference in New Issue
Block a user