diff options
author | Nick Sanders <nsanders@chromium.org> | 2016-10-28 16:23:12 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-11-02 17:39:56 -0700 |
commit | a04fc68e721c8165ce570d8929aef1330cf72df1 (patch) | |
tree | 309d560207dc27ca6ee72b3593630282c7c93434 /chip | |
parent | d4bff62d36cf42e7b28929baff64b0d99bf95362 (diff) | |
download | chrome-ec-a04fc68e721c8165ce570d8929aef1330cf72df1.tar.gz |
usb_i2c: refactor into common
This combines stm32 and chip/g usb_i2c interfaces so they
will not diverge. Note that this fixes the chip/g implementation
to use 8-bit i2c addresses.
BUG=chrome-os-partner:57059
BRANCH=none
TEST=servod interacts with servo_micro and servo_v4
Change-Id: Ibff217d84b132556202c8a71e3d42c07d546c634
Reviewed-on: https://chromium-review.googlesource.com/405108
Commit-Ready: Nick Sanders <nsanders@chromium.org>
Tested-by: Nick Sanders <nsanders@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/g/build.mk | 1 | ||||
-rw-r--r-- | chip/g/usb_i2c.c | 114 | ||||
-rw-r--r-- | chip/g/usb_i2c.h | 152 | ||||
-rw-r--r-- | chip/stm32/build.mk | 1 |
4 files changed, 0 insertions, 268 deletions
diff --git a/chip/g/build.mk b/chip/g/build.mk index c6325f4884..df028da65b 100644 --- a/chip/g/build.mk +++ b/chip/g/build.mk @@ -56,7 +56,6 @@ chip-$(CONFIG_WATCHDOG)+=watchdog.o chip-$(CONFIG_USB)+=usb.o usb_endpoints.o chip-$(CONFIG_USB_CONSOLE)+=usb_console.o chip-$(CONFIG_USB_HID)+=usb_hid.o -chip-$(CONFIG_USB_I2C)+=usb_i2c.o chip-$(CONFIG_USB_BLOB)+=blob.o chip-$(CONFIG_USB_SPI)+=usb_spi.o chip-$(CONFIG_RDD)+=rdd.o diff --git a/chip/g/usb_i2c.c b/chip/g/usb_i2c.c deleted file mode 100644 index b3094d716b..0000000000 --- a/chip/g/usb_i2c.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "common.h" -#include "link_defs.h" -#include "registers.h" -#include "i2c.h" -#include "usb_descriptor.h" -#include "util.h" - -#include "common.h" -#include "console.h" -#include "consumer.h" -#include "queue.h" -#include "queue_policies.h" -#include "producer.h" -#include "task.h" -#include "usb-stream.h" -#include "usb_i2c.h" - - -#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) - -USB_I2C_CONFIG(i2c, - USB_IFACE_I2C, - USB_STR_I2C_NAME, - USB_EP_I2C) - -static int16_t usb_i2c_map_error(int error) -{ - switch (error) { - case EC_SUCCESS: return USB_I2C_SUCCESS; - case EC_ERROR_TIMEOUT: return USB_I2C_TIMEOUT; - case EC_ERROR_BUSY: return USB_I2C_BUSY; - default: return USB_I2C_UNKNOWN_ERROR | (error & 0x7fff); - } -} - -static uint8_t usb_i2c_read_packet(struct usb_i2c_config const *config) -{ - return QUEUE_REMOVE_UNITS(config->consumer.queue, config->buffer, - queue_count(config->consumer.queue)); -} - -static void usb_i2c_write_packet(struct usb_i2c_config const *config, - uint8_t count) -{ - QUEUE_ADD_UNITS(config->tx_queue, config->buffer, count); -} - -void usb_i2c_deferred(struct usb_i2c_config const *config) -{ - /* - * And if there is a USB packet waiting we process it and generate a - * response. - */ - uint8_t count = usb_i2c_read_packet(config); - int portindex = (config->buffer[0] >> 0) & 0xff; - uint8_t slave_addr = (config->buffer[0] >> 8) & 0xff; - int write_count = (config->buffer[1] >> 0) & 0xff; - int read_count = (config->buffer[1] >> 8) & 0xff; - int port; - int rv; - - config->buffer[0] = 0; - config->buffer[1] = 0; - - if (!count || (!read_count && !write_count)) - return; - - if (write_count > USB_I2C_MAX_WRITE_COUNT || - write_count != (count - 4)) { - config->buffer[0] = USB_I2C_WRITE_COUNT_INVALID; - } else if (read_count > USB_I2C_MAX_READ_COUNT) { - config->buffer[0] = USB_I2C_READ_COUNT_INVALID; - } else if (portindex >= i2c_ports_used) { - config->buffer[0] = USB_I2C_PORT_INVALID; - } else { - rv = usb_i2c_board_enable(); - if (rv) { - config->buffer[0] = usb_i2c_map_error(rv); - } else { - port = i2c_ports[portindex].port; - config->buffer[0] = usb_i2c_map_error( - i2c_xfer(port, slave_addr, - (uint8_t *)(config->buffer + 2), - write_count, - (uint8_t *)(config->buffer + 2), - read_count, I2C_XFER_SINGLE)); - usb_i2c_board_disable(1); - } - } - - usb_i2c_write_packet(config, read_count + 4); -} - -static void usb_i2c_written(struct consumer const *consumer, size_t count) -{ - struct usb_i2c_config const *config = - DOWNCAST(consumer, struct usb_i2c_config, consumer); - - hook_call_deferred(config->deferred, 0); -} - -static void usb_i2c_flush(struct consumer const *consumer) -{ -} - -struct consumer_ops const usb_i2c_consumer_ops = { - .written = usb_i2c_written, - .flush = usb_i2c_flush, -}; diff --git a/chip/g/usb_i2c.h b/chip/g/usb_i2c.h deleted file mode 100644 index 401b20a0c5..0000000000 --- a/chip/g/usb_i2c.h +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "consumer.h" -#include "producer.h" -#include "registers.h" -#include "task.h" -#include "usb_descriptor.h" - -#ifndef __CROS_USB_I2C_H -#define __CROS_USB_I2C_H - -/* - * Command: - * +----------+-----------+---------------+---------------+---------------+ - * | port: 1B | addr: 1B | wr count : 1B | rd count : 1B | data : <= 60B | - * +----------+-----------+---------------+---------------+---------------+ - * - * port address: 1 byte, i2c interface index - * - * slave address: 1 byte, i2c 7-bit bus address - * - * write count: 1 byte, zero based count of bytes to write - * - * read count: 1 byte, zero based count of bytes to read - * - * data: write payload up to 60 bytes of data to write, - * length must match write count - * - * Response: - * +-------------+---+---+-----------------------+ - * | status : 2B | 0 | 0 | read payload : <= 60B | - * +-------------+---+---+-----------------------+ - * - * status: 2 byte status - * 0x0000: Success - * 0x0001: I2C timeout - * 0x0002: Busy, try again - * This can happen if someone else has acquired the shared memory - * buffer that the I2C driver uses as /dev/null - * 0x0003: Write count invalid (> 60 bytes, or mismatch with payload) - * 0x0004: Read count invalid (> 60 bytes) - * 0x0005: The port specified is invalid. - * 0x8000: Unknown error mask - * The bottom 15 bits will contain the bottom 15 bits from the EC - * error code. - * - * read payload: up to 60 bytes of data read from I2C, length will match - * requested read count - */ - -enum usb_i2c_error { - USB_I2C_SUCCESS = 0x0000, - USB_I2C_TIMEOUT = 0x0001, - USB_I2C_BUSY = 0x0002, - USB_I2C_WRITE_COUNT_INVALID = 0x0003, - USB_I2C_READ_COUNT_INVALID = 0x0004, - USB_I2C_PORT_INVALID = 0x0005, - USB_I2C_UNKNOWN_ERROR = 0x8000, -}; - - -#define USB_I2C_MAX_WRITE_COUNT 60 -#define USB_I2C_MAX_READ_COUNT 60 - -BUILD_ASSERT(USB_MAX_PACKET_SIZE == (1 + 1 + 1 + 1 + USB_I2C_MAX_WRITE_COUNT)); -BUILD_ASSERT(USB_MAX_PACKET_SIZE == (2 + 1 + 1 + USB_I2C_MAX_READ_COUNT)); - -/* - * Compile time Per-USB gpio configuration stored in flash. Instances of this - * structure are provided by the user of the USB i2c. This structure binds - * together all information required to operate a USB i2c. - */ -struct usb_i2c_config { - uint16_t *buffer; - - /* Deferred function to call to handle SPI request. */ - const struct deferred_data *deferred; - - struct consumer const consumer; - struct queue const *tx_queue; -}; - -extern struct consumer_ops const usb_i2c_consumer_ops; - -/* - * Convenience macro for defining a USB I2C bridge driver. - * - * NAME is used to construct the names of the trampoline functions and the - * usb_i2c_config struct, the latter is just called NAME. - * - * INTERFACE is the index of the USB interface to associate with this - * I2C driver. - * - * INTERFACE_NAME is the index of the USB string descriptor (iInterface). - * - * ENDPOINT is the index of the USB bulk endpoint used for receiving and - * transmitting bytes. - */ -#define USB_I2C_CONFIG(NAME, \ - INTERFACE, \ - INTERFACE_NAME, \ - ENDPOINT) \ - static uint16_t \ - CONCAT2(NAME, _buffer_)[USB_MAX_PACKET_SIZE/2]; \ - static void CONCAT2(NAME, _deferred_)(void); \ - DECLARE_DEFERRED(CONCAT2(NAME, _deferred_)); \ - static struct queue const CONCAT2(NAME, _to_usb_); \ - static struct queue const CONCAT3(usb_to_, NAME, _); \ - USB_STREAM_CONFIG_FULL(CONCAT2(NAME, _usb_), \ - INTERFACE, \ - USB_CLASS_VENDOR_SPEC, \ - USB_SUBCLASS_GOOGLE_I2C, \ - USB_PROTOCOL_GOOGLE_I2C, \ - INTERFACE_NAME, \ - ENDPOINT, \ - USB_MAX_PACKET_SIZE, \ - USB_MAX_PACKET_SIZE, \ - CONCAT3(usb_to_, NAME, _), \ - CONCAT2(NAME, _to_usb_)) \ - struct usb_i2c_config const NAME = { \ - .buffer = CONCAT2(NAME, _buffer_), \ - .deferred = &CONCAT2(NAME, _deferred__data), \ - .consumer = { \ - .queue = &CONCAT3(usb_to_, NAME, _), \ - .ops = &usb_i2c_consumer_ops, \ - }, \ - .tx_queue = &CONCAT2(NAME, _to_usb_), \ - }; \ - static struct queue const CONCAT2(NAME, _to_usb_) = \ - QUEUE_DIRECT(USB_MAX_PACKET_SIZE, uint8_t, \ - null_producer, CONCAT2(NAME, _usb_).consumer); \ - static struct queue const CONCAT3(usb_to_, NAME, _) = \ - QUEUE_DIRECT(USB_MAX_PACKET_SIZE, uint8_t, \ - CONCAT2(NAME, _usb_).producer, NAME.consumer); \ - static void CONCAT2(NAME, _deferred_)(void) \ - { usb_i2c_deferred(&NAME); } - -/* - * Handle I2C request in a deferred callback. - */ -void usb_i2c_deferred(struct usb_i2c_config const *config); - -/* - * These functions should be implemented by the board to provide any board - * specific operations required to enable or disable access to the I2C device. - */ -int usb_i2c_board_enable(void); -void usb_i2c_board_disable(int debounce); -#endif /* __CROS_USB_I2C_H */ diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk index 52749e1d16..8575463c7a 100644 --- a/chip/stm32/build.mk +++ b/chip/stm32/build.mk @@ -70,5 +70,4 @@ chip-$(CONFIG_USB_GPIO)+=usb_gpio.o chip-$(CONFIG_USB_HID)+=usb_hid.o chip-$(CONFIG_USB_PD_TCPC)+=usb_pd_phy.o chip-$(CONFIG_USB_SPI)+=usb_spi.o -chip-$(CONFIG_USB_I2C)+=usb_i2c.o endif |