Commit 3aa78e0c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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 0998d063 ("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
  ...
parents dc5ef1f5 25f311fa
* TI - TSC ADC (Touschscreen and analog digital converter)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Required properties:
- child "tsc"
ti,wires: Wires refer to application modes i.e. 4/5/8 wire touchscreen
support on the platform.
ti,x-plate-resistance: X plate resistance
ti,coordiante-readouts: The sequencer supports a total of 16
programmable steps each step is used to
read a single coordinate. A single
readout is enough but multiple reads can
increase the quality.
A value of 5 means, 5 reads for X, 5 for
Y and 2 for Z (always). This utilises 12
of the 16 software steps available. The
remaining 4 can be used by the ADC.
ti,wire-config: Different boards could have a different order for
connecting wires on touchscreen. We need to provide an
8 bit number where in the 1st four bits represent the
analog lines and the next 4 bits represent positive/
negative terminal on that input line. Notations to
represent the input lines and terminals resoectively
is as follows:
AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
XP = 0, XN = 1, YP = 2, YN = 3.
- child "adc"
ti,adc-channels: List of analog inputs available for ADC.
AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
Example:
tscadc: tscadc@44e0d000 {
compatible = "ti,am3359-tscadc";
tsc {
ti,wires = <4>;
ti,x-plate-resistance = <200>;
ti,coordiante-readouts = <5>;
ti,wire-config = <0x00 0x11 0x22 0x33>;
};
adc {
ti,adc-channels = <4 5 6 7>;
};
}
* Maxim MAX8998, National/TI LP3974 multi-function device
The Maxim MAX8998 is a multi-function device which includes voltage/current
regulators, real time clock, battery charging controller and several
other sub-blocks. It is interfaced using an I2C interface. Each sub-block
is addressed by the host system using different i2c slave address.
PMIC sub-block
--------------
The PMIC sub-block contains a number of voltage and current regulators,
with controllable parameters and dynamic voltage scaling capability.
In addition, it includes a real time clock and battery charging controller
as well. It is accessible at I2C address 0x66.
Required properties:
- compatible: Should be one of the following:
- "maxim,max8998" for Maxim MAX8998
- "national,lp3974" or "ti,lp3974" for National/TI LP3974.
- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
Optional properties:
- interrupt-parent: Specifies the phandle of the interrupt controller to which
the interrupts from MAX8998 are routed to.
- interrupts: Interrupt specifiers for two interrupt sources.
- First interrupt specifier is for main interrupt.
- Second interrupt specifier is for power-on/-off interrupt.
- max8998,pmic-buck1-dvs-gpios: GPIO specifiers for two host gpios used
for buck 1 dvs. The format of the gpio specifier depends on the gpio
controller.
- max8998,pmic-buck2-dvs-gpio: GPIO specifier for host gpio used
for buck 2 dvs. The format of the gpio specifier depends on the gpio
controller.
- max8998,pmic-buck1-default-dvs-idx: Default voltage setting selected from
the possible 4 options selectable by the dvs gpios. The value of this
property should be 0, 1, 2 or 3. If not specified or out of range,
a default value of 0 is taken.
- max8998,pmic-buck2-default-dvs-idx: Default voltage setting selected from
the possible 2 options selectable by the dvs gpios. The value of this
property should be 0 or 1. If not specified or out of range, a default
value of 0 is taken.
- max8998,pmic-buck-voltage-lock: If present, disallows changing of
preprogrammed buck dvfs voltages.
Additional properties required if max8998,pmic-buck1-dvs-gpios is defined:
- max8998,pmic-buck1-dvs-voltage: An array of 4 voltage values in microvolts
for buck1 regulator that can be selected using dvs gpio.
Additional properties required if max8998,pmic-buck2-dvs-gpio is defined:
- max8998,pmic-buck2-dvs-voltage: An array of 2 voltage values in microvolts
for buck2 regulator that can be selected using dvs gpio.
Regulators: All the regulators of MAX8998 to be instantiated shall be
listed in a child node named 'regulators'. Each regulator is represented
by a child node of the 'regulators' node.
regulator-name {
/* standard regulator bindings here */
};
Following regulators of the MAX8998 PMIC block are supported. Note that
the 'n' in regulator name, as in LDOn or BUCKn, represents the LDO or BUCK
number as described in MAX8998 datasheet.
- LDOn
- valid values for n are 2 to 17
- Example: LDO2, LDO10, LDO17
- BUCKn
- valid values for n are 1 to 4.
- Example: BUCK1, BUCK2, BUCK3, BUCK4
- ENVICHG: Battery Charging Current Monitor Output. This is a fixed
voltage type regulator
- ESAFEOUT1: (ldo19)
- ESAFEOUT2: (ld020)
Standard regulator bindings are used inside regulator subnodes. Check
Documentation/devicetree/bindings/regulator/regulator.txt
for more details.
Example:
pmic@66 {
compatible = "maxim,max8998-pmic";
reg = <0x66>;
interrupt-parent = <&wakeup_eint>;
interrupts = <4 0>, <3 0>;
/* Buck 1 DVS settings */
max8998,pmic-buck1-default-dvs-idx = <0>;
max8998,pmic-buck1-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
<&gpx0 1 1 0 0>; /* SET2 */
max8998,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
<1000000>, <950000>;
/* Buck 2 DVS settings */
max8998,pmic-buck2-default-dvs-idx = <0>;
max8998,pmic-buck2-dvs-gpio = <&gpx0 0 3 0 0>; /* SET3 */
max8998,pmic-buck2-dvs-voltage = <1350000>, <1300000>;
/* Regulators to instantiate */
regulators {
ldo2_reg: LDO2 {
regulator-name = "VDD_ALIVE_1.1V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "VDD_ARM_1.2V";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
};
};
Texas Instruments TWL family (twl4030) reset and power management module
The power management module inside the TWL family provides several facilities
to control the power resources, including power scripts. For now, the
binding only supports the complete shutdown of the system after poweroff.
Required properties:
- compatible : must be "ti,twl4030-power"
Optional properties:
- ti,use_poweroff: With this flag, the chip will initiates an ACTIVE-to-OFF or
SLEEP-to-OFF transition when the system poweroffs.
Example:
&i2c1 {
clock-frequency = <2600000>;
twl: twl@48 {
reg = <0x48>;
interrupts = <7>; /* SYS_NIRQ cascaded to intc */
interrupt-parent = <&intc>;
twl_power: power {
compatible = "ti,twl4030-power";
ti,use_poweroff;
};
};
};
......@@ -18,20 +18,20 @@ For twl6030 regulators/LDOs
- "ti,twl6030-vdd1" for VDD1 SMPS
- "ti,twl6030-vdd2" for VDD2 SMPS
- "ti,twl6030-vdd3" for VDD3 SMPS
For twl6025 regulators/LDOs
For twl6032 regulators/LDOs
- compatible:
- "ti,twl6025-ldo1" for LDO1 LDO
- "ti,twl6025-ldo2" for LDO2 LDO
- "ti,twl6025-ldo3" for LDO3 LDO
- "ti,twl6025-ldo4" for LDO4 LDO
- "ti,twl6025-ldo5" for LDO5 LDO
- "ti,twl6025-ldo6" for LDO6 LDO
- "ti,twl6025-ldo7" for LDO7 LDO
- "ti,twl6025-ldoln" for LDOLN LDO
- "ti,twl6025-ldousb" for LDOUSB LDO
- "ti,twl6025-smps3" for SMPS3 SMPS
- "ti,twl6025-smps4" for SMPS4 SMPS
- "ti,twl6025-vio" for VIO SMPS
- "ti,twl6032-ldo1" for LDO1 LDO
- "ti,twl6032-ldo2" for LDO2 LDO
- "ti,twl6032-ldo3" for LDO3 LDO
- "ti,twl6032-ldo4" for LDO4 LDO
- "ti,twl6032-ldo5" for LDO5 LDO
- "ti,twl6032-ldo6" for LDO6 LDO
- "ti,twl6032-ldo7" for LDO7 LDO
- "ti,twl6032-ldoln" for LDOLN LDO
- "ti,twl6032-ldousb" for LDOUSB LDO
- "ti,twl6032-smps3" for SMPS3 SMPS
- "ti,twl6032-smps4" for SMPS4 SMPS
- "ti,twl6032-vio" for VIO SMPS
For twl4030 regulators/LDOs
- compatible:
- "ti,twl4030-vaux1" for VAUX1 LDO
......
......@@ -8,7 +8,7 @@ TWL6030 USB COMPARATOR
usb interrupt number that raises VBUS interrupts when the controller has to
act as device
- usb-supply : phandle to the regulator device tree node. It should be vusb
if it is twl6030 or ldousb if it is twl6025 subclass.
if it is twl6030 or ldousb if it is twl6032 subclass.
twl6030-usb {
compatible = "ti,twl6030-usb";
......
......@@ -5500,9 +5500,12 @@ F: include/media/mt9v032.h
MULTIFUNCTION DEVICES (MFD)
M: Samuel Ortiz <sameo@linux.intel.com>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git
M: Lee Jones <lee.jones@linaro.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-fixes.git
S: Supported
F: drivers/mfd/
F: include/linux/mfd/
MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
M: Chris Ball <cjb@laptop.org>
......
......@@ -474,3 +474,17 @@
phy_id = <&davinci_mdio>, <1>;
phy-mode = "rgmii-txid";
};
&tscadc {
status = "okay";
tsc {
ti,wires = <4>;
ti,x-plate-resistance = <200>;
ti,coordiante-readouts = <5>;
ti,wire-config = <0x00 0x11 0x22 0x33>;
};
adc {
ti,adc-channels = <4 5 6 7>;
};
};
......@@ -502,6 +502,23 @@
status = "disabled";
};
tscadc: tscadc@44e0d000 {
compatible = "ti,am3359-tscadc";
reg = <0x44e0d000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <16>;
ti,hwmods = "adc_tsc";
status = "disabled";
tsc {
compatible = "ti,am3359-tsc";
};
am335x_adc: adc {
#io-channel-cells = <1>;
compatible = "ti,am3359-adc";
};
};
gpmc: gpmc@50000000 {
compatible = "ti,am3352-gpmc";
ti,hwmods = "gpmc";
......
......@@ -377,12 +377,8 @@ static struct max8998_platform_data aquila_max8998_pdata = {
.buck1_set1 = S5PV210_GPH0(3),
.buck1_set2 = S5PV210_GPH0(4),
.buck2_set3 = S5PV210_GPH0(5),
.buck1_voltage1 = 1200000,
.buck1_voltage2 = 1200000,
.buck1_voltage3 = 1200000,
.buck1_voltage4 = 1200000,
.buck2_voltage1 = 1200000,
.buck2_voltage2 = 1200000,
.buck1_voltage = { 1200000, 1200000, 1200000, 1200000 },
.buck2_voltage = { 1200000, 1200000 },
};
#endif
......
......@@ -580,12 +580,8 @@ static struct max8998_platform_data goni_max8998_pdata = {
.buck1_set1 = S5PV210_GPH0(3),
.buck1_set2 = S5PV210_GPH0(4),
.buck2_set3 = S5PV210_GPH0(5),
.buck1_voltage1 = 1200000,
.buck1_voltage2 = 1200000,
.buck1_voltage3 = 1200000,
.buck1_voltage4 = 1200000,
.buck2_voltage1 = 1200000,
.buck2_voltage2 = 1200000,
.buck1_voltage = { 1200000, 1200000, 1200000, 1200000 },
.buck2_voltage = { 1200000, 1200000 },
};
#endif
......
......@@ -52,8 +52,6 @@ source "drivers/i2c/Kconfig"
source "drivers/spi/Kconfig"
source "drivers/ssbi/Kconfig"
source "drivers/hsi/Kconfig"
source "drivers/pps/Kconfig"
......
......@@ -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
......
......@@ -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");
......
......@@ -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 {