/** * tc3589x_reg_read() - read a single TC3589x register * @tc3589x: Device to read from * @reg: Register to read
*/ int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg)
{ int ret;
ret = i2c_smbus_read_byte_data(tc3589x->i2c, reg); if (ret < 0)
dev_err(tc3589x->dev, "failed to read reg %#x: %d\n",
reg, ret);
/** * tc3589x_reg_write() - write a single TC3589x register * @tc3589x: Device to write to * @reg: Register to read * @data: Value to write
*/ int tc3589x_reg_write(struct tc3589x *tc3589x, u8 reg, u8 data)
{ int ret;
ret = i2c_smbus_write_byte_data(tc3589x->i2c, reg, data); if (ret < 0)
dev_err(tc3589x->dev, "failed to write reg %#x: %d\n",
reg, ret);
/** * tc3589x_block_read() - read multiple TC3589x registers * @tc3589x: Device to read from * @reg: First register * @length: Number of registers * @values: Buffer to write to
*/ int tc3589x_block_read(struct tc3589x *tc3589x, u8 reg, u8 length, u8 *values)
{ int ret;
ret = i2c_smbus_read_i2c_block_data(tc3589x->i2c, reg, length, values); if (ret < 0)
dev_err(tc3589x->dev, "failed to read regs %#x: %d\n",
reg, ret);
/** * tc3589x_set_bits() - set the value of a bitfield in a TC3589x register * @tc3589x: Device to write to * @reg: Register to write * @mask: Mask of bits to set * @val: Value to set
*/ int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val)
{ int ret;
mutex_lock(&tc3589x->lock);
ret = tc3589x_reg_read(tc3589x, reg); if (ret < 0) goto out;
again:
status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); if (status < 0) return IRQ_NONE;
while (status) { int bit = __ffs(status); int virq = irq_find_mapping(tc3589x->domain, bit);
handle_nested_irq(virq);
status &= ~(1 << bit);
}
/* * A dummy read or write (to any register) appears to be necessary to * have the last interrupt clear (for example, GPIO IC write) take * effect. In such a case, recheck for any interrupt which is still * pending.
*/
status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); if (status) goto again;
/* * Put everything except the IRQ module into reset; * also spare the GPIO module for any pin initialization * done during pre-kernel boot
*/
ret = tc3589x_reg_write(tc3589x, TC3589x_RSTCTRL,
TC3589x_RSTCTRL_TIMRST
| TC3589x_RSTCTRL_ROTRST
| TC3589x_RSTCTRL_KBDRST); if (ret < 0) return ret;
if (!pdata) {
pdata = tc3589x_of_probe(&i2c->dev, &version); if (IS_ERR(pdata)) {
dev_err(&i2c->dev, "No platform data or DT found\n"); return PTR_ERR(pdata);
}
} else { /* When not probing from device tree we have this ID */
version = id->driver_data;
}
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
| I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO;
tc3589x = devm_kzalloc(&i2c->dev, sizeof(struct tc3589x),
GFP_KERNEL); if (!tc3589x) return -ENOMEM;
switch (version) { case TC3589X_TC35893: case TC3589X_TC35895: case TC3589X_TC35896:
tc3589x->num_gpio = 20; break; case TC3589X_TC35890: case TC3589X_TC35892: case TC3589X_TC35894: case TC3589X_UNKNOWN: default:
tc3589x->num_gpio = 24; break;
}
i2c_set_clientdata(i2c, tc3589x);
ret = tc3589x_chip_init(tc3589x); if (ret) return ret;
ret = tc3589x_irq_init(tc3589x, np); if (ret) return ret;
ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "tc3589x", tc3589x); if (ret) {
dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret); return ret;
}
ret = tc3589x_device_init(tc3589x); if (ret) {
dev_err(tc3589x->dev, "failed to add child devices\n"); return ret;
}
staticint tc3589x_suspend(struct device *dev)
{ struct tc3589x *tc3589x = dev_get_drvdata(dev); struct i2c_client *client = tc3589x->i2c; int ret = 0;
/* put the system to sleep mode */ if (!device_may_wakeup(&client->dev))
ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE,
TC3589x_CLKMODE_MODCTL_SLEEP);
return ret;
}
staticint tc3589x_resume(struct device *dev)
{ struct tc3589x *tc3589x = dev_get_drvdata(dev); struct i2c_client *client = tc3589x->i2c; int ret = 0;
/* enable the system into operation */ if (!device_may_wakeup(&client->dev))
ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE,
TC3589x_CLKMODE_MODCTL_OPERATION);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.