Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0db0f26c authored by Andrey Smirnov's avatar Andrey Smirnov Committed by Linus Walleij
Browse files

pinctrl-sx150x: Convert driver to use regmap API



To allow for future code simplification

Tested-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Acked-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Signed-off-by: default avatarAndrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent b30d31e4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ config PINCTRL_SX150X
	select PINCONF
	select GENERIC_PINCONF
	select GPIOLIB_IRQCHIP
	select REGMAP
	help
	  Say yes here to provide support for Semtech SX150x-series I2C
	  GPIO expanders as pinctrl module.
+56 −46
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
 * GNU General Public License for more details.
 */

#include <linux/regmap.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -45,6 +46,7 @@ enum {
};
enum {
	SX150X_789_REG_MISC_AUTOCLEAR_OFF = 1 << 0,
	SX150X_MAX_REGISTER = 0xad,
};

struct sx150x_123_pri {
@@ -102,6 +104,7 @@ struct sx150x_pinctrl {
	struct pinctrl_desc pinctrl_desc;
	struct gpio_chip gpio;
	struct irq_chip irq_chip;
	struct regmap *regmap;
	struct {
		int update;
		u32 sense;
@@ -256,30 +259,6 @@ static const struct sx150x_device_data sx1503q_device_data = {
	.npins  = 16, /* oscio not available */
};

static s32 sx150x_i2c_write(struct i2c_client *client, u8 reg, u8 val)
{
	s32 err = i2c_smbus_write_byte_data(client, reg, val);

	if (err < 0)
		dev_warn(&client->dev,
			"i2c write fail: can't write %02x to %02x: %d\n",
			val, reg, err);
	return err;
}

static s32 sx150x_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
{
	s32 err = i2c_smbus_read_byte_data(client, reg);

	if (err >= 0)
		*val = err;
	else
		dev_warn(&client->dev,
			"i2c read fail: can't read from %02x: %d\n",
			reg, err);
	return err;
}

/*
 * These utility functions solve the common problem of locating and setting
 * configuration bits.  Configuration bits are grouped into registers
@@ -312,30 +291,32 @@ static int sx150x_write_cfg(struct i2c_client *client,
			    u8 offset, u8 width, u8 reg, u8 val)
{
	u8  mask;
	u8  data;
	unsigned int data;
	u8  shift;
	int err;
	struct sx150x_pinctrl *pctl = i2c_get_clientdata(client);

	sx150x_find_cfg(offset, width, &reg, &mask, &shift);
	err = sx150x_i2c_read(client, reg, &data);
	err = regmap_read(pctl->regmap, reg, &data);
	if (err < 0)
		return err;

	data &= ~mask;
	data |= (val << shift) & mask;
	return sx150x_i2c_write(client, reg, data);
	return regmap_write(pctl->regmap, reg, data);
}

static int sx150x_read_cfg(struct i2c_client *client,
			   u8 offset, u8 width, u8 reg)
{
	u8  mask;
	u8  data;
	unsigned int data;
	u8  shift;
	int err;
	struct sx150x_pinctrl *pctl = i2c_get_clientdata(client);

	sx150x_find_cfg(offset, width, &reg, &mask, &shift);
	err = sx150x_i2c_read(client, reg, &data);
	err = regmap_read(pctl->regmap, reg, &data);
	if (err < 0)
		return err;

@@ -463,9 +444,8 @@ static void sx150x_gpio_set(struct gpio_chip *chip, unsigned int offset,
	struct sx150x_pinctrl *pctl = gpiochip_get_data(chip);

	if (sx150x_pin_is_oscio(pctl, offset)) {

		mutex_lock(&pctl->lock);
		sx150x_i2c_write(pctl->client,
		regmap_write(pctl->regmap,
			     pctl->data->pri.x789.reg_clock,
			     (value ? 0x1f : 0x10));
		mutex_unlock(&pctl->lock);
@@ -567,17 +547,17 @@ static irqreturn_t sx150x_irq_thread_fn(int irq, void *dev_id)
	unsigned int sub_irq;
	unsigned int n;
	s32 err;
	u8 val;
	unsigned int val;
	int i;

	for (i = (pctl->data->ngpios / 8) - 1; i >= 0; --i) {
		err = sx150x_i2c_read(pctl->client,
		err = regmap_read(pctl->regmap,
				  pctl->data->reg_irq_src - i,
				  &val);
		if (err < 0)
			continue;

		err = sx150x_i2c_write(pctl->client,
		err = regmap_write(pctl->regmap,
				   pctl->data->reg_irq_src - i,
				   val);
		if (err < 0)
@@ -650,13 +630,13 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
	u32 arg;

	if (sx150x_pin_is_oscio(pctl, pin)) {
		u8 data;
		unsigned int data;

		switch (param) {
		case PIN_CONFIG_DRIVE_PUSH_PULL:
		case PIN_CONFIG_OUTPUT:
			mutex_lock(&pctl->lock);
			ret = sx150x_i2c_read(pctl->client,
			ret = regmap_read(pctl->regmap,
					  pctl->data->pri.x789.reg_clock,
					  &data);
			mutex_unlock(&pctl->lock);
@@ -904,7 +884,7 @@ static int sx150x_init_io(struct sx150x_pinctrl *pctl, u8 base, u16 cfg)
	unsigned int n;

	for (n = 0; err >= 0 && n < (pctl->data->ngpios / 8); ++n)
		err = sx150x_i2c_write(pctl->client, base - n, cfg >> (n * 8));
		err = regmap_write(pctl->regmap, base - n, cfg >> (n * 8));
	return err;
}

@@ -953,7 +933,7 @@ static int sx150x_init_misc(struct sx150x_pinctrl *pctl)
		return -EINVAL;
	}

	return sx150x_i2c_write(pctl->client, reg, value);
	return i2c_smbus_write_byte_data(pctl->client, reg, value);
}

static int sx150x_init_hw(struct sx150x_pinctrl *pctl)
@@ -997,6 +977,26 @@ static int sx150x_init_hw(struct sx150x_pinctrl *pctl)
	return 0;
}

static bool sx150x_reg_volatile(struct device *dev, unsigned int reg)
{
	struct sx150x_pinctrl *pctl = i2c_get_clientdata(to_i2c_client(dev));

	return reg == pctl->data->reg_irq_src     ||
	       reg == pctl->data->reg_irq_src - 1 ||
	       reg == pctl->data->reg_data        ||
	       reg == pctl->data->reg_data - 1;
}

const struct regmap_config sx150x_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,

	.cache_type = REGCACHE_RBTREE,

	.max_register = SX150X_MAX_REGISTER,
	.volatile_reg = sx150x_reg_volatile,
};

static int sx150x_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
@@ -1013,6 +1013,8 @@ static int sx150x_probe(struct i2c_client *client,
	if (!pctl)
		return -ENOMEM;

	i2c_set_clientdata(client, pctl);

	pctl->dev = dev;
	pctl->client = client;

@@ -1024,6 +1026,14 @@ static int sx150x_probe(struct i2c_client *client,
	if (!pctl->data)
		return -EINVAL;

	pctl->regmap = devm_regmap_init_i2c(client, &sx150x_regmap_config);
	if (IS_ERR(pctl->regmap)) {
		ret = PTR_ERR(pctl->regmap);
		dev_err(dev, "Failed to allocate register map: %d\n",
			ret);
		return ret;
	}

	mutex_init(&pctl->lock);

	ret = sx150x_init_hw(pctl);