Skip to content

Commit

Permalink
Merge tag 'chrome-for-linus' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/olof/chrome-platform

Pull chrome platform updates from Olof Johansson:
 "Here's a set of updates to the Chrome OS platform drivers for this
  merge window.

  Main new things this cycle is:

   - Driver changes to expose the lightbar to users.  With this, you can
     make your own blinkenlights on Chromebook Pixels.

   - Changes in the way that the atmel_mxt trackpads are probed.  The
     laptop driver is trying to be smart and not instantiate the devices
     that don't answer to probe.  For the trackpad that can come up in
     two modes (bootloader or regular), this gets complicated since the
     driver already knows how to handle the two modes including the
     actual addresses used.  So now the laptop driver needs to know more
     too, instantiating the regular address even if the bootloader one
     is the probe that passed.

   - mfd driver improvements by Javier Martines Canillas, and a few
     bugfixes from him, kbuild and myself"

* tag 'chrome-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/olof/chrome-platform:
  platform/chrome: chromeos_laptop - instantiate Atmel at primary address
  platform/chrome: cros_ec_lpc - Depend on X86 || COMPILE_TEST
  platform/chrome: cros_ec_lpc - Include linux/io.h header file
  platform/chrome: fix platform_no_drv_owner.cocci warnings
  platform/chrome: cros_ec_lightbar - fix duplicate const warning
  platform/chrome: cros_ec_dev - fix Unknown escape '%' warning
  platform/chrome: Expose Chrome OS Lightbar to users
  platform/chrome: Create sysfs attributes for the ChromeOS EC
  mfd: cros_ec: Instantiate ChromeOS EC character device
  platform/chrome: Add Chrome OS EC userspace device interface
  platform/chrome: Add cros_ec_lpc driver for x86 devices
  mfd: cros_ec: Add char dev and virtual dev pointers
  mfd: cros_ec: Use fixed size arrays to transfer data with the EC
  • Loading branch information
torvalds committed Apr 26, 2015
2 parents 7f9f443 + 96cba9b commit 36a8032
Show file tree
Hide file tree
Showing 13 changed files with 1,384 additions and 71 deletions.
1 change: 1 addition & 0 deletions Documentation/ioctl/ioctl-number.txt
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ Code Seq#(hex) Include File Comments
0xDB 00-0F drivers/char/mwave/mwavepub.h
0xDD 00-3F ZFCP device driver see drivers/s390/scsi/
<mailto:[email protected]>
0xEC 00-01 drivers/platform/chrome/cros_ec_dev.h ChromeOS EC driver
0xF3 00-3F drivers/usb/misc/sisusbvga/sisusb.h sisfb (in development)
<mailto:[email protected]>
0xF4 00-1F video/mbxfb.h mbxfb
Expand Down
51 changes: 10 additions & 41 deletions drivers/i2c/busses/i2c-cros-ec-tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,72 +182,41 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[],
const u16 bus_num = bus->remote_bus;
int request_len;
int response_len;
u8 *request = NULL;
u8 *response = NULL;
int result;
struct cros_ec_command msg;
struct cros_ec_command msg = { };

request_len = ec_i2c_count_message(i2c_msgs, num);
if (request_len < 0) {
dev_warn(dev, "Error constructing message %d\n", request_len);
result = request_len;
goto exit;
return request_len;
}

response_len = ec_i2c_count_response(i2c_msgs, num);
if (response_len < 0) {
/* Unexpected; no errors should come when NULL response */
dev_warn(dev, "Error preparing response %d\n", response_len);
result = response_len;
goto exit;
}

if (request_len <= ARRAY_SIZE(bus->request_buf)) {
request = bus->request_buf;
} else {
request = kzalloc(request_len, GFP_KERNEL);
if (request == NULL) {
result = -ENOMEM;
goto exit;
}
}
if (response_len <= ARRAY_SIZE(bus->response_buf)) {
response = bus->response_buf;
} else {
response = kzalloc(response_len, GFP_KERNEL);
if (response == NULL) {
result = -ENOMEM;
goto exit;
}
return response_len;
}

result = ec_i2c_construct_message(request, i2c_msgs, num, bus_num);
result = ec_i2c_construct_message(msg.outdata, i2c_msgs, num, bus_num);
if (result)
goto exit;
return result;

msg.version = 0;
msg.command = EC_CMD_I2C_PASSTHRU;
msg.outdata = request;
msg.outsize = request_len;
msg.indata = response;
msg.insize = response_len;

result = cros_ec_cmd_xfer(bus->ec, &msg);
if (result < 0)
goto exit;
return result;

result = ec_i2c_parse_response(response, i2c_msgs, &num);
result = ec_i2c_parse_response(msg.indata, i2c_msgs, &num);
if (result < 0)
goto exit;
return result;

/* Indicate success by saying how many messages were sent */
result = num;
exit:
if (request != bus->request_buf)
kfree(request);
if (response != bus->response_buf)
kfree(response);

return result;
return num;
}

static u32 ec_i2c_functionality(struct i2c_adapter *adap)
Expand Down
13 changes: 8 additions & 5 deletions drivers/input/keyboard/cros_ec_keyb.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,19 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,

static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
{
int ret;
struct cros_ec_command msg = {
.version = 0,
.command = EC_CMD_MKBP_STATE,
.outdata = NULL,
.outsize = 0,
.indata = kb_state,
.insize = ckdev->cols,
};

return cros_ec_cmd_xfer(ckdev->ec, &msg);
ret = cros_ec_cmd_xfer(ckdev->ec, &msg);
if (ret < 0)
return ret;

memcpy(kb_state, msg.indata, ckdev->cols);

return 0;
}

static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
Expand Down
19 changes: 11 additions & 8 deletions drivers/mfd/cros_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,11 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
ret = ec_dev->cmd_xfer(ec_dev, msg);
if (msg->result == EC_RES_IN_PROGRESS) {
int i;
struct cros_ec_command status_msg;
struct ec_response_get_comms_status status;
struct cros_ec_command status_msg = { };
struct ec_response_get_comms_status *status;

status_msg.version = 0;
status_msg.command = EC_CMD_GET_COMMS_STATUS;
status_msg.outdata = NULL;
status_msg.outsize = 0;
status_msg.indata = (uint8_t *)&status;
status_msg.insize = sizeof(status);
status_msg.insize = sizeof(*status);

/*
* Query the EC's status until it's no longer busy or
Expand All @@ -98,7 +94,10 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
msg->result = status_msg.result;
if (status_msg.result != EC_RES_SUCCESS)
break;
if (!(status.flags & EC_COMMS_STATUS_PROCESSING))

status = (struct ec_response_get_comms_status *)
status_msg.indata;
if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
break;
}
}
Expand All @@ -119,6 +118,10 @@ static const struct mfd_cell cros_devs[] = {
.id = 2,
.of_compatible = "google,cros-ec-i2c-tunnel",
},
{
.name = "cros-ec-ctl",
.id = 3,
},
};

int cros_ec_register(struct cros_ec_device *ec_dev)
Expand Down
26 changes: 23 additions & 3 deletions drivers/platform/chrome/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

menuconfig CHROME_PLATFORMS
bool "Platform support for Chrome hardware"
depends on X86
depends on X86 || ARM
---help---
Say Y here to get to see options for platform support for
various Chromebooks and Chromeboxes. This option alone does
Expand All @@ -16,8 +16,7 @@ if CHROME_PLATFORMS

config CHROMEOS_LAPTOP
tristate "Chrome OS Laptop"
depends on I2C
depends on DMI
depends on I2C && DMI && X86
---help---
This driver instantiates i2c and smbus devices such as
light sensors and touchpads.
Expand All @@ -27,6 +26,7 @@ config CHROMEOS_LAPTOP

config CHROMEOS_PSTORE
tristate "Chrome OS pstore support"
depends on X86
---help---
This module instantiates the persistent storage on x86 ChromeOS
devices. It can be used to store away console logs and crash
Expand All @@ -38,5 +38,25 @@ config CHROMEOS_PSTORE
If you have a supported Chromebook, choose Y or M here.
The module will be called chromeos_pstore.

config CROS_EC_CHARDEV
tristate "Chrome OS Embedded Controller userspace device interface"
depends on MFD_CROS_EC
---help---
This driver adds support to talk with the ChromeOS EC from userspace.

If you have a supported Chromebook, choose Y or M here.
The module will be called cros_ec_dev.

config CROS_EC_LPC
tristate "ChromeOS Embedded Controller (LPC)"
depends on MFD_CROS_EC && (X86 || COMPILE_TEST)
help
If you say Y here, you get support for talking to the ChromeOS EC
over an LPC bus. This uses a simple byte-level protocol with a
checksum. This is used for userspace access only. The kernel
typically has its own communication methods.

To compile this driver as a module, choose M here: the
module will be called cros_ec_lpc.

endif # CHROMEOS_PLATFORMS
3 changes: 3 additions & 0 deletions drivers/platform/chrome/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@

obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o
cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o cros_ec_lightbar.o
obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o
obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o
35 changes: 26 additions & 9 deletions drivers/platform/chrome/chromeos_laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,13 @@ static struct i2c_client *__add_probed_i2c_device(
const char *name,
int bus,
struct i2c_board_info *info,
const unsigned short *addrs)
const unsigned short *alt_addr_list)
{
const struct dmi_device *dmi_dev;
const struct dmi_dev_onboard *dev_data;
struct i2c_adapter *adapter;
struct i2c_client *client;
struct i2c_client *client = NULL;
const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END };

if (bus < 0)
return NULL;
Expand Down Expand Up @@ -169,8 +170,28 @@ static struct i2c_client *__add_probed_i2c_device(
return NULL;
}

/* add the i2c device */
client = i2c_new_probed_device(adapter, info, addrs, NULL);
/*
* 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);
}
}

if (!client)
pr_notice("%s failed to register device %d-%02x\n",
__func__, bus, info->addr);
Expand Down Expand Up @@ -254,12 +275,10 @@ static struct i2c_client *add_i2c_device(const char *name,
enum i2c_adapter_type type,
struct i2c_board_info *info)
{
const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END };

return __add_probed_i2c_device(name,
find_i2c_adapter_num(type),
info,
addr_list);
NULL);
}

static int setup_cyapa_tp(enum i2c_adapter_type type)
Expand All @@ -275,7 +294,6 @@ static int setup_cyapa_tp(enum i2c_adapter_type type)
static int setup_atmel_224s_tp(enum i2c_adapter_type type)
{
const unsigned short addr_list[] = { ATMEL_TP_I2C_BL_ADDR,
ATMEL_TP_I2C_ADDR,
I2C_CLIENT_END };
if (tp)
return 0;
Expand All @@ -289,7 +307,6 @@ static int setup_atmel_224s_tp(enum i2c_adapter_type type)
static int setup_atmel_1664s_ts(enum i2c_adapter_type type)
{
const unsigned short addr_list[] = { ATMEL_TS_I2C_BL_ADDR,
ATMEL_TS_I2C_ADDR,
I2C_CLIENT_END };
if (ts)
return 0;
Expand Down
Loading

0 comments on commit 36a8032

Please sign in to comment.