pca955x
struct pca955x *pca955x;
static int pca955x_write_psc(struct pca955x *pca955x, int n, u8 val)
u8 cmd = pca955x_num_input_regs(pca955x->chipdef->bits) + (2 * n);
ret = i2c_smbus_write_byte_data(pca955x->client, cmd, val);
dev_err(&pca955x->client->dev, "%s: reg 0x%x, val 0x%x, err %d\n", __func__, n,
static int pca955x_write_pwm(struct pca955x *pca955x, int n, u8 val)
u8 cmd = pca955x_num_input_regs(pca955x->chipdef->bits) + 1 + (2 * n);
ret = i2c_smbus_write_byte_data(pca955x->client, cmd, val);
dev_err(&pca955x->client->dev, "%s: reg 0x%x, val 0x%x, err %d\n", __func__, n,
static int pca955x_write_ls(struct pca955x *pca955x, int n, u8 val)
u8 cmd = pca955x_num_input_regs(pca955x->chipdef->bits) + 4 + n;
ret = i2c_smbus_write_byte_data(pca955x->client, cmd, val);
dev_err(&pca955x->client->dev, "%s: reg 0x%x, val 0x%x, err %d\n", __func__, n,
static int pca955x_read_ls(struct pca955x *pca955x, int n, u8 *val)
u8 cmd = pca955x_num_input_regs(pca955x->chipdef->bits) + 4 + n;
ret = i2c_smbus_read_byte_data(pca955x->client, cmd);
dev_err(&pca955x->client->dev, "%s: reg 0x%x, err %d\n", __func__, n, ret);
static int pca955x_read_pwm(struct pca955x *pca955x, int n, u8 *val)
u8 cmd = pca955x_num_input_regs(pca955x->chipdef->bits) + 1 + (2 * n);
ret = i2c_smbus_read_byte_data(pca955x->client, cmd);
dev_err(&pca955x->client->dev, "%s: reg 0x%x, err %d\n", __func__, n, ret);
static int pca955x_read_psc(struct pca955x *pca955x, int n, u8 *val)
cmd = pca955x_num_input_regs(pca955x->chipdef->bits) + (2 * n);
ret = i2c_smbus_read_byte_data(pca955x->client, cmd);
dev_err(&pca955x->client->dev, "%s: reg 0x%x, err %d\n", __func__, n, ret);
struct pca955x *pca955x = pca955x_led->pca955x;
ret = pca955x_read_ls(pca955x, pca955x_led->led_num / 4, &ls);
ret = pca955x_read_pwm(pca955x, 1, &pwm);
struct pca955x *pca955x = pca955x_led->pca955x;
mutex_lock(&pca955x->lock);
ret = pca955x_read_ls(pca955x, reg, &ls);
if (test_bit(pca955x_led->led_num, &pca955x->active_blink)) {
clear_bit(pca955x_led->led_num, &pca955x->active_blink);
ret = pca955x_write_pwm(pca955x, 1, 255 - value);
ret = pca955x_write_ls(pca955x, reg, ls);
mutex_unlock(&pca955x->lock);
static u8 pca955x_period_to_psc(struct pca955x *pca955x, unsigned long period)
period *= pca955x->chipdef->blink_div;
static unsigned long pca955x_psc_to_period(struct pca955x *pca955x, u8 psc)
period /= pca955x->chipdef->blink_div;
struct pca955x *pca955x = pca955x_led->pca955x;
mutex_lock(&pca955x->lock);
if (period < pca955x_psc_to_period(pca955x, 0) ||
period > pca955x_psc_to_period(pca955x, 0xff)) {
period = pca955x->active_blink ? pca955x->blink_period :
if (!pca955x->active_blink ||
pca955x->active_blink == BIT(pca955x_led->led_num) ||
pca955x->blink_period == period) {
u8 psc = pca955x_period_to_psc(pca955x, period);
&pca955x->active_blink)) {
ret = pca955x_read_ls(pca955x, reg, &ls);
ret = pca955x_write_ls(pca955x, reg, ls);
ret = pca955x_write_pwm(pca955x, 0, 128);
if (pca955x->blink_period != period) {
pca955x->blink_period = period;
ret = pca955x_write_psc(pca955x, 0, psc);
period = pca955x_psc_to_period(pca955x, psc);
mutex_unlock(&pca955x->lock);
struct pca955x *pca955x = gpiochip_get_data(gc);
return test_and_set_bit(offset, &pca955x->active_pins) ? -EBUSY : 0;
struct pca955x *pca955x = gpiochip_get_data(gc);
clear_bit(offset, &pca955x->active_pins);
struct pca955x *pca955x = gpiochip_get_data(gc);
struct pca955x_led *led = &pca955x->leds[offset];
struct pca955x *pca955x = gpiochip_get_data(gc);
struct pca955x_led *led = &pca955x->leds[offset];
pca955x_read_input(pca955x->client, led->led_num / 8, ®);
struct pca955x *pca955x = gpiochip_get_data(gc);
struct pca955x_led *led = &pca955x->leds[offset];
struct pca955x *pca955x;
pca955x = devm_kzalloc(&client->dev, sizeof(*pca955x), GFP_KERNEL);
if (!pca955x)
pca955x->leds = devm_kcalloc(&client->dev, chip->bits,
if (!pca955x->leds)
i2c_set_clientdata(client, pca955x);
mutex_init(&pca955x->lock);
pca955x->client = client;
pca955x->chipdef = chip;
pca955x->blink_period = PCA955X_BLINK_DEFAULT_MS;
pca955x_led = &pca955x->leds[i];
pca955x_led->pca955x = pca955x;
set_bit(i, &pca955x->active_blink);
set_bit(i, &pca955x->active_pins);
err = pca955x_write_ls(pca955x, i, ls2[i]);
err = pca955x_read_psc(pca955x, 0, &psc0);
psc0 = pca955x_period_to_psc(pca955x, pca955x->blink_period);
err = pca955x_write_psc(pca955x, 0, psc0);
pca955x->blink_period = pca955x_psc_to_period(pca955x, psc0);
err = pca955x_write_psc(pca955x, 1, 0);
pca955x->gpio.label = "gpio-pca955x";
pca955x->gpio.direction_input = pca955x_gpio_direction_input;
pca955x->gpio.direction_output = pca955x_gpio_direction_output;
pca955x->gpio.set = pca955x_gpio_set_value;
pca955x->gpio.get = pca955x_gpio_get_value;
pca955x->gpio.request = pca955x_gpio_request_pin;
pca955x->gpio.free = pca955x_gpio_free_pin;
pca955x->gpio.can_sleep = 1;
pca955x->gpio.base = -1;
pca955x->gpio.ngpio = chip->bits;
pca955x->gpio.parent = &client->dev;
pca955x->gpio.owner = THIS_MODULE;
err = devm_gpiochip_add_data(&client->dev, &pca955x->gpio,
pca955x);
pca955x->gpio.parent = NULL;
pca955x->gpio.base, pca955x->gpio.base +
pca955x->gpio.ngpio - 1);