diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 11:10:27 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 11:10:27 -0700 |
commit | 3aa78e0cb5c9b8b4ed2a617bb1e1542bfb508379 (patch) | |
tree | a446e1f8a81f63933423ef11ea7d31cc918b30f6 /drivers | |
parent | dc5ef1f56968c67e81ad1c81ab7dce678f480285 (diff) | |
parent | 25f311fa58c18c19ae1348336265ccb8368638f0 (diff) |
Merge tag 'mfd-3.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next
Pull MFD update from Samuel Ortiz:
"For the 3.11 merge we only have one new MFD driver for the Kontron
PLD.
But we also have:
- Support for the TPS659038 PMIC from the palmas driver.
- Intel's Coleto Creek and Avoton SoCs support from the lpc_ich
driver.
- RTL8411B support from the rtsx driver.
- More DT support for the Arizona, max8998, twl4030-power and the
ti_am335x_tsadc drivers.
- The SSBI driver move under MFD.
- A conversion to the devm_* API for most of the MFD drivers.
- The twl4030-power got split from twl-core into its own module.
- A major ti_am335x_adc cleanup, leading to a proper DT support.
- Our regular arizona and wm* updates and cleanups from the Wolfson
folks.
- A better error handling and initialization, and a regulator
subdevice addition for the 88pm80x driver.
- A bulk platform_set_drvdata() call removal that's no longer need
since commit 0998d0631001 ("device-core: Ensure drvdata = NULL when
no driver is bound")
* tag 'mfd-3.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next: (102 commits)
mfd: sec: Provide max_register to regmap
mfd: wm8994: Remove duplicate check for active JACKDET
MAINTAINERS: Add include directory to MFD file patterns
mfd: sec: Remove fields not used since regmap conversion
watchdog: Kontron PLD watchdog timer driver
mfd: max8998: Add support for Device Tree
regulator: max8998: Use arrays for specifying voltages in platform data
mfd: max8998: Add irq domain support
regulator: palmas: Add TPS659038 support
mfd: Kontron PLD mfd driver
mfd: palmas: Add TPS659038 PMIC support
mfd: palmas: Add SMPS10_BOOST feature
mfd: palmas: Check if irq is valid
mfd: lpc_ich: iTCO_wdt patch for Intel Coleto Creek DeviceIDs
mfd: twl-core: Change TWL6025 references to TWL6032
mfd: davinci_voicecodec: Fix build breakage
mfd: vexpress: Make the driver optional for arm and arm64
mfd: htc-egpio: Use devm_ioremap_nocache() instead of ioremap_nocache()
mfd: davinci_voicecodec: Convert to use devm_* APIs
mfd: twl4030-power: Fix relocking on error
...
Diffstat (limited to 'drivers')
71 files changed, 4383 insertions, 892 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index ae050b54c36..aa43b911cce 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -52,8 +52,6 @@ source "drivers/i2c/Kconfig" source "drivers/spi/Kconfig" -source "drivers/ssbi/Kconfig" - source "drivers/hsi/Kconfig" source "drivers/pps/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 336b0ad0acd..ab93de8297f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -117,7 +117,6 @@ obj-y += firmware/ obj-$(CONFIG_CRYPTO) += crypto/ obj-$(CONFIG_SUPERH) += sh/ obj-$(CONFIG_ARCH_SHMOBILE) += sh/ -obj-$(CONFIG_SSBI) += ssbi/ ifndef CONFIG_ARCH_USES_GETTIMEOFFSET obj-y += clocksource/ endif diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 5f9a7e7d313..4427e8e46a7 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -22,13 +22,18 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/iio/iio.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/iio/machine.h> +#include <linux/iio/driver.h> #include <linux/mfd/ti_am335x_tscadc.h> -#include <linux/platform_data/ti_am335x_adc.h> struct tiadc_device { struct ti_tscadc_dev *mfd_tscadc; int channels; + u8 channel_line[8]; + u8 channel_step[8]; }; static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) @@ -42,10 +47,20 @@ static void tiadc_writel(struct tiadc_device *adc, unsigned int reg, writel(val, adc->mfd_tscadc->tscadc_base + reg); } +static u32 get_adc_step_mask(struct tiadc_device *adc_dev) +{ + u32 step_en; + + step_en = ((1 << adc_dev->channels) - 1); + step_en <<= TOTAL_STEPS - adc_dev->channels + 1; + return step_en; +} + static void tiadc_step_config(struct tiadc_device *adc_dev) { unsigned int stepconfig; - int i, channels = 0, steps; + int i, steps; + u32 step_en; /* * There are 16 configurable steps and 8 analog input @@ -58,43 +73,63 @@ static void tiadc_step_config(struct tiadc_device *adc_dev) */ steps = TOTAL_STEPS - adc_dev->channels; - channels = TOTAL_CHANNELS - adc_dev->channels; - stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; - for (i = (steps + 1); i <= TOTAL_STEPS; i++) { - tiadc_writel(adc_dev, REG_STEPCONFIG(i), - stepconfig | STEPCONFIG_INP(channels)); - tiadc_writel(adc_dev, REG_STEPDELAY(i), + for (i = 0; i < adc_dev->channels; i++) { + int chan; + + chan = adc_dev->channel_line[i]; + tiadc_writel(adc_dev, REG_STEPCONFIG(steps), + stepconfig | STEPCONFIG_INP(chan)); + tiadc_writel(adc_dev, REG_STEPDELAY(steps), STEPCONFIG_OPENDLY); - channels++; + adc_dev->channel_step[i] = steps; + steps++; } - tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); + step_en = get_adc_step_mask(adc_dev); + am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); } +static const char * const chan_name_ain[] = { + "AIN0", + "AIN1", + "AIN2", + "AIN3", + "AIN4", + "AIN5", + "AIN6", + "AIN7", +}; + static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) { + struct tiadc_device *adc_dev = iio_priv(indio_dev); struct iio_chan_spec *chan_array; + struct iio_chan_spec *chan; int i; indio_dev->num_channels = channels; - chan_array = kcalloc(indio_dev->num_channels, + chan_array = kcalloc(channels, sizeof(struct iio_chan_spec), GFP_KERNEL); - if (chan_array == NULL) return -ENOMEM; - for (i = 0; i < (indio_dev->num_channels); i++) { - struct iio_chan_spec *chan = chan_array + i; + chan = chan_array; + for (i = 0; i < channels; i++, chan++) { + chan->type = IIO_VOLTAGE; chan->indexed = 1; - chan->channel = i; + chan->channel = adc_dev->channel_line[i]; chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + chan->datasheet_name = chan_name_ain[chan->channel]; + chan->scan_type.sign = 'u'; + chan->scan_type.realbits = 12; + chan->scan_type.storagebits = 32; } indio_dev->channels = chan_array; - return indio_dev->num_channels; + return 0; } static void tiadc_channels_remove(struct iio_dev *indio_dev) @@ -108,7 +143,9 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, { struct tiadc_device *adc_dev = iio_priv(indio_dev); int i; - unsigned int fifo1count, readx1; + unsigned int fifo1count, read; + u32 step = UINT_MAX; + bool found = false; /* * When the sub-system is first enabled, @@ -121,14 +158,26 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, * Hence we need to flush out this data. */ + for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) { + if (chan->channel == adc_dev->channel_line[i]) { + step = adc_dev->channel_step[i]; + break; + } + } + if (WARN_ON_ONCE(step == UINT_MAX)) + return -EINVAL; + fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); for (i = 0; i < fifo1count; i++) { - readx1 = tiadc_readl(adc_dev, REG_FIFO1); - if (i == chan->channel) - *val = readx1 & 0xfff; + read = tiadc_readl(adc_dev, REG_FIFO1); + if (read >> 16 == step) { + *val = read & 0xfff; + found = true; + } } - tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); - + am335x_tsc_se_update(adc_dev->mfd_tscadc); + if (found == false) + return -EBUSY; return IIO_VAL_INT; } @@ -140,13 +189,15 @@ static int tiadc_probe(struct platform_device *pdev) { struct iio_dev *indio_dev; struct tiadc_device *adc_dev; - struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; - struct mfd_tscadc_board *pdata; + struct device_node *node = pdev->dev.of_node; + struct property *prop; + const __be32 *cur; int err; + u32 val; + int channels = 0; - pdata = tscadc_dev->dev->platform_data; - if (!pdata || !pdata->adc_init) { - dev_err(&pdev->dev, "Could not find platform data\n"); + if (!node) { + dev_err(&pdev->dev, "Could not find valid DT data.\n"); return -EINVAL; } @@ -158,8 +209,13 @@ static int tiadc_probe(struct platform_device *pdev) } adc_dev = iio_priv(indio_dev); - adc_dev->mfd_tscadc = tscadc_dev; - adc_dev->channels = pdata->adc_init->adc_channels; + adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev); + + of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { + adc_dev->channel_line[channels] = val; + channels++; + } + adc_dev->channels = channels; indio_dev->dev.parent = &pdev->dev; indio_dev->name = dev_name(&pdev->dev); @@ -191,10 +247,15 @@ err_ret: static int tiadc_remove(struct platform_device *pdev) { struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct tiadc_device *adc_dev = iio_priv(indio_dev); + u32 step_en; iio_device_unregister(indio_dev); tiadc_channels_remove(indio_dev); + step_en = get_adc_step_mask(adc_dev); + am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en); + iio_device_free(indio_dev); return 0; @@ -205,9 +266,10 @@ static int tiadc_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct tiadc_device *adc_dev = iio_priv(indio_dev); - struct ti_tscadc_dev *tscadc_dev = dev->platform_data; + struct ti_tscadc_dev *tscadc_dev; unsigned int idle; + tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); if (!device_may_wakeup(tscadc_dev->dev)) { idle = tiadc_readl(adc_dev, REG_CTRL); idle &= ~(CNTRLREG_TSCSSENB); @@ -243,16 +305,22 @@ static const struct dev_pm_ops tiadc_pm_ops = { #define TIADC_PM_OPS NULL #endif +static const struct of_device_id ti_adc_dt_ids[] = { + { .compatible = "ti,am3359-adc", }, + { } +}; +MODULE_DEVICE_TABLE(of, ti_adc_dt_ids); + static struct platform_driver tiadc_driver = { .driver = { - .name = "tiadc", + .name = "TI-am335x-adc", .owner = THIS_MODULE, .pm = TIADC_PM_OPS, + .of_match_table = of_match_ptr(ti_adc_dt_ids), }, .probe = tiadc_probe, .remove = tiadc_remove, }; - module_platform_driver(tiadc_driver); MODULE_DESCRIPTION("TI ADC controller driver"); diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 50fb1293874..e1c5300cacf 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -24,8 +24,9 @@ #include <linux/clk.h> #include <linux/platform_device.h> #include <linux/io.h> -#include <linux/input/ti_am335x_tsc.h> #include <linux/delay.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <linux/mfd/ti_am335x_tscadc.h> @@ -33,6 +34,13 @@ #define SEQ_SETTLE 275 #define MAX_12BIT ((1 << 12) - 1) +static const int config_pins[] = { + STEPCONFIG_XPP, + STEPCONFIG_XNN, + STEPCONFIG_YPP, + STEPCONFIG_YNN, +}; + struct titsc { struct input_dev *input; struct ti_tscadc_dev *mfd_tscadc; @@ -40,7 +48,10 @@ struct titsc { unsigned int wires; unsigned int x_plate_resistance; bool pen_down; - int steps_to_configure; + int coordinate_readouts; + u32 config_inp[4]; + u32 bit_xp, bit_xn, bit_yp, bit_yn; + u32 inp_xp, inp_xn, inp_yp, inp_yn; }; static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) @@ -54,92 +65,153 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg, writel(val, tsc->mfd_tscadc->tscadc_base + reg); } +static int titsc_config_wires(struct titsc *ts_dev) +{ + u32 analog_line[4]; + u32 wire_order[4]; + int i, bit_cfg; + + for (i = 0; i < 4; i++) { + /* + * Get the order in which TSC wires are attached + * w.r.t. each of the analog input lines on the EVM. + */ + analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4; + wire_order[i] = ts_dev->config_inp[i] & 0x0F; + if (WARN_ON(analog_line[i] > 7)) + return -EINVAL; + if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins))) + return -EINVAL; + } + + for (i = 0; i < 4; i++) { + int an_line; + int wi_order; + + an_line = analog_line[i]; + wi_order = wire_order[i]; + bit_cfg = config_pins[wi_order]; + if (bit_cfg == 0) + return -EINVAL; + switch (wi_order) { + case 0: + ts_dev->bit_xp = bit_cfg; + ts_dev->inp_xp = an_line; + break; + + case 1: + ts_dev->bit_xn = bit_cfg; + ts_dev->inp_xn = an_line; + break; + + case 2: + ts_dev->bit_yp = bit_cfg; + ts_dev->inp_yp = an_line; + break; + case 3: + ts_dev->bit_yn = bit_cfg; + ts_dev->inp_yn = an_line; + break; + } + } + return 0; +} + static void titsc_step_config(struct titsc *ts_dev) { unsigned int config; - int i, total_steps; - - /* Configure the Step registers */ - total_steps = 2 * ts_dev->steps_to_configure; + int i; + int end_step; + u32 stepenable; config = STEPCONFIG_MODE_HWSYNC | - STEPCONFIG_AVG_16 | STEPCONFIG_XPP; + STEPCONFIG_AVG_16 | ts_dev->bit_xp; switch (ts_dev->wires) { case 4: - config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; + config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; break; case 5: - config |= STEPCONFIG_YNN | - STEPCONFIG_INP_AN4 | STEPCONFIG_XNN | - STEPCONFIG_YPP; + config |= ts_dev->bit_yn | + STEPCONFIG_INP_AN4 | ts_dev->bit_xn | + ts_dev->bit_yp; break; case 8: - config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; + config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; break; } - for (i = 1; i <= ts_dev->steps_to_configure; i++) { + /* 1 … coordinate_readouts is for X */ + end_step = ts_dev->coordinate_readouts; + for (i = 0; i < end_step; i++) { titsc_writel(ts_dev, REG_STEPCONFIG(i), config); titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); } config = 0; config = STEPCONFIG_MODE_HWSYNC | - STEPCONFIG_AVG_16 | STEPCONFIG_YNN | - STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; + STEPCONFIG_AVG_16 | ts_dev->bit_yn | + STEPCONFIG_INM_ADCREFM; switch (ts_dev->wires) { case 4: - config |= STEPCONFIG_YPP; + config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); break; case 5: - config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 | - STEPCONFIG_XNP | STEPCONFIG_YPN; + config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 | + ts_dev->bit_xn | ts_dev->bit_yp; break; case 8: - config |= STEPCONFIG_YPP; + config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); break; } - for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) { + /* coordinate_readouts … coordinate_readouts * 2 is for Y */ + end_step = ts_dev->coordinate_readouts * 2; + for (i = ts_dev->coordinate_readouts; i < end_step; i++) { titsc_writel(ts_dev, REG_STEPCONFIG(i), config); titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); } - config = 0; /* Charge step configuration */ - config = STEPCONFIG_XPP | STEPCONFIG_YNN | + config = ts_dev->bit_xp | ts_dev->bit_yn | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | - STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1; + STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp); titsc_writel(ts_dev, REG_CHARGECONFIG, config); titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); - config = 0; - /* Configure to calculate pressure */ + /* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */ config = STEPCONFIG_MODE_HWSYNC | - STEPCONFIG_AVG_16 | STEPCONFIG_YPP | - STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM; - titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); - titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), + STEPCONFIG_AVG_16 | ts_dev->bit_yp | + ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | + STEPCONFIG_INP(ts_dev->inp_xp); + titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); + titsc_writel(ts_dev, REG_STEPDELAY(end_step), STEPCONFIG_OPENDLY); - config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1; - titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); - titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), + end_step++; + config |= STEPCONFIG_INP(ts_dev->inp_yn); + titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); + titsc_writel(ts_dev, REG_STEPDELAY(end_step), STEPCONFIG_OPENDLY); - titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); + /* The steps1 … end and bit 0 for TS_Charge */ + stepenable = (1 << (end_step + 2)) - 1; + am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable); } static void titsc_read_coordinates(struct titsc *ts_dev, - unsigned int *x, unsigned int *y) + u32 *x, u32 *y, u32 *z1, u32 *z2) { unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); unsigned int prev_val_x = ~0, prev_val_y = ~0; unsigned int prev_diff_x = ~0, prev_diff_y = ~0; unsigned int read, diff; unsigned int i, channel; + unsigned int creads = ts_dev->coordinate_readouts; + *z1 = *z2 = 0; + if (fifocount % (creads * 2 + 2)) + fifocount -= fifocount % (creads * 2 + 2); /* * Delta filter is used to remove large variations in sampled * values from ADC. The filter tries to predict where the next @@ -148,32 +220,32 @@ static void titsc_read_coordinates(struct titsc *ts_dev, * algorithm compares the difference with that of a present value, * if true the value is reported to the sub system. */ |