diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 10:58:17 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 10:58:17 -0800 |
commit | ac26663572db5b64522b92f3941a58678a832a36 (patch) | |
tree | 3a8d27153de37cb3f3fb0ff6843a1e727c961005 /drivers/mfd/cros_ec_spi.c | |
parent | d4371f94bc003e912d4825f5c4bdf57959857073 (diff) | |
parent | 02915661dbb91b25b621ab3f387ab55311bded7f (diff) | |
download | blackbird-obmc-linux-ac26663572db5b64522b92f3941a58678a832a36.tar.gz blackbird-obmc-linux-ac26663572db5b64522b92f3941a58678a832a36.zip |
Merge tag 'mfd-3.14-1' of git://git.linaro.org/people/ljones/mfd
Pull MFD changes from Lee Jones:
"New drivers
- Samsung Maxim 14577; Micro USB, Regulator, IRQ Controller and
Battery Charger
- TI/National Semiconductor LP3943 I2C GPIO Expander and PWM
Generator
Existing driver adaptions
- Expansion of Wolfson Arizona DSP and High-Pass filter controls
- TI TWL6040 default Regmap support and Regcache addition/bypass
- Some nice Smatch catch fixes
- Conversion of TI OMAP-USB and TI TWL6030 to endian neutralness
- ChromeOS EC timing (delay) adaptions and added dependency on OF
- Many constifications of 'struct {mfd_cell,regmap_irq,et.al}'
- Watchdog support added for NVIDIA AS3722
- Convert functions to static in TI AM335x
- Realigned previously defeated functionality in TI AM335x
- IIO ADC-TSC concurrency dead-lock/timeout resolution
- Addition of Power Management and Clock support for Samsung core
- DEFINE_PCI_DEVICE_TABLE macro removal from MFD Subsystem
- Greater use of irqdomain functionality in ST-E AB8500
- Removal of 'include/linux/mfd/abx500/ab8500-gpio.h'
- Wolfson WM831x PMIC Power Management changes s/poweroff/shutdown/
- Device Tree documentation added for TI/Nat Semi LP3943
- Version detection and voltage tables for TI TPS6586x PMIC devices
- Simplification of Freescale MC13XXX (de-)initialisation routines
- Clean-up and simplification of the Realtek parent driver
- Added support for RTL8402 Realtek PCI-Express card reader
- Resource leak fix for Maxim 77686
- Possible suspend BUG() fix in OMAP USB TLL
- Support for new Wolfson WM5110 Revision (D)
- Testing of automatic assignment of of_node in mfd_add_device()
- Reversion of the above when it started to cause issues
- Remove legacy Platform Data from;
TI TWL Core, Qualcomm SSBI and ST-E ABx500 Pinctrl
- Clean-ups; tabbing issues, function name changes, 'drvdata = NULL'
removal, unused uninitialised warning mitigation, error
message clarity, removal of redundant/duplicate checks,
licensing (GPL -> GPL2), coding consistency, duplicate
function declaration, ret checks, commit corrections,
redundant of_match_ptr() helper removal, spelling,
#if-deffery removal and header guards name changes"
* tag 'mfd-3.14-1' of git://git.linaro.org/people/ljones/mfd: (78 commits)
mfd: wm5110: Add register patch for rev D chip
mfd: omap-usb-tll: Don't hold lock during pm_runtime_get/put_sync()
gpio: lp3943: Remove redundant of_match_ptr helper
mfd: sta2x11-mfd: Use named constants for pci_power_t values
Documentation: mfd: Fix LDO index in s2mps11.txt
mfd: Cleanup mfd-mcp-sa11x0.h header
mfd: max8997: Use "IS_ENABLED(CONFIG_OF)" for DT code.
mfd: twl6030: Fix endianness problem in IRQ handler
mfd: sec-core: Add cells for S5M8767-clocks
mfd: max14577: Remove redundant of_match_ptr helper
mfd: twl6040: Fix sparse non static symbol warning
mfd: Revert "mfd: Always assign of_node in mfd_add_device()"
mfd: rtsx: Fix sparse non static symbol warning
mfd: max77693: Set proper maximum register for MUIC regmap
mfd: max77686: Fix regmap resource leak on driver remove
mfd: Represent correct filenames in file headers
mfd: rtsx: Add support for card reader rtl8402
mfd: rtsx: Add set pull control macro and simplify rtl8411
mfd: max8997: Enforce mfd_add_devices() return value check
mfd: mc13xxx: Simplify probe() & remove()
...
Diffstat (limited to 'drivers/mfd/cros_ec_spi.c')
-rw-r--r-- | drivers/mfd/cros_ec_spi.c | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c index 367ccb58ecb1..84af8d7a4295 100644 --- a/drivers/mfd/cros_ec_spi.c +++ b/drivers/mfd/cros_ec_spi.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/mfd/cros_ec.h> #include <linux/mfd/cros_ec_commands.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spi/spi.h> @@ -50,10 +51,11 @@ /* * Time between raising the SPI chip select (for the end of a * transaction) and dropping it again (for the next transaction). - * If we go too fast, the EC will miss the transaction. It seems - * that 50us is enough with the 16MHz STM32 EC. + * If we go too fast, the EC will miss the transaction. We know that we + * need at least 70 us with the 16 MHz STM32 EC, so go with 200 us to be + * safe. */ -#define EC_SPI_RECOVERY_TIME_NS (50 * 1000) +#define EC_SPI_RECOVERY_TIME_NS (200 * 1000) /** * struct cros_ec_spi - information about a SPI-connected EC @@ -61,10 +63,13 @@ * @spi: SPI device we are connected to * @last_transfer_ns: time that we last finished a transfer, or 0 if there * if no record + * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that + * is sent when we want to turn off CS at the end of a transaction. */ struct cros_ec_spi { struct spi_device *spi; s64 last_transfer_ns; + unsigned int end_of_msg_delay; }; static void debug_packet(struct device *dev, const char *name, u8 *ptr, @@ -75,7 +80,9 @@ static void debug_packet(struct device *dev, const char *name, u8 *ptr, dev_dbg(dev, "%s: ", name); for (i = 0; i < len; i++) - dev_cont(dev, " %02x", ptr[i]); + pr_cont(" %02x", ptr[i]); + + pr_cont("\n"); #endif } @@ -105,7 +112,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, /* Receive data until we see the header byte */ deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS); do { - memset(&trans, '\0', sizeof(trans)); + memset(&trans, 0, sizeof(trans)); trans.cs_change = 1; trans.rx_buf = ptr = ec_dev->din; trans.len = EC_MSG_PREAMBLE_COUNT; @@ -157,7 +164,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n", todo, need_len, ptr - ec_dev->din); - memset(&trans, '\0', sizeof(trans)); + memset(&trans, 0, sizeof(trans)); trans.cs_change = 1; trans.rx_buf = ptr; trans.len = todo; @@ -217,7 +224,7 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, /* Transmit phase - send our message */ debug_packet(ec_dev->dev, "out", ec_dev->dout, len); - memset(&trans, '\0', sizeof(trans)); + memset(&trans, 0, sizeof(trans)); trans.tx_buf = ec_dev->dout; trans.len = len; trans.cs_change = 1; @@ -235,6 +242,17 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, /* turn off CS */ spi_message_init(&msg); + + if (ec_spi->end_of_msg_delay) { + /* + * Add delay for last transaction, to ensure the rising edge + * doesn't come too soon after the end of the data. + */ + memset(&trans, 0, sizeof(trans)); + trans.delay_usecs = ec_spi->end_of_msg_delay; + spi_message_add_tail(&trans, &msg); + } + final_ret = spi_sync(ec_spi->spi, &msg); ktime_get_ts(&ts); ec_spi->last_transfer_ns = timespec_to_ns(&ts); @@ -281,7 +299,18 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, return 0; } -static int cros_ec_probe_spi(struct spi_device *spi) +static void cros_ec_spi_dt_probe(struct cros_ec_spi *ec_spi, struct device *dev) +{ + struct device_node *np = dev->of_node; + u32 val; + int ret; + + ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val); + if (!ret) + ec_spi->end_of_msg_delay = val; +} + +static int cros_ec_spi_probe(struct spi_device *spi) { struct device *dev = &spi->dev; struct cros_ec_device *ec_dev; @@ -302,6 +331,9 @@ static int cros_ec_probe_spi(struct spi_device *spi) if (!ec_dev) return -ENOMEM; + /* Check for any DT properties */ + cros_ec_spi_dt_probe(ec_spi, dev); + spi_set_drvdata(spi, ec_dev); ec_dev->name = "SPI"; ec_dev->dev = dev; @@ -323,7 +355,7 @@ static int cros_ec_probe_spi(struct spi_device *spi) return 0; } -static int cros_ec_remove_spi(struct spi_device *spi) +static int cros_ec_spi_remove(struct spi_device *spi) { struct cros_ec_device *ec_dev; @@ -364,12 +396,12 @@ static struct spi_driver cros_ec_driver_spi = { .owner = THIS_MODULE, .pm = &cros_ec_spi_pm_ops, }, - .probe = cros_ec_probe_spi, - .remove = cros_ec_remove_spi, + .probe = cros_ec_spi_probe, + .remove = cros_ec_spi_remove, .id_table = cros_ec_spi_id, }; module_spi_driver(cros_ec_driver_spi); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("ChromeOS EC multi function device (SPI)"); |