mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
i2c-host for v7.1, part 2
- cx92755: convert I2C bindings to DT schema - mediatek: add optional bus power management during transfers - pxa: handle early bus busy condition -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQScDfrjQa34uOld1VLaeAVmJtMtbgUCaeQfzQAKCRDaeAVmJtMt bhZbAP4yxgj5FEkHaKYHEsUwXfh4zUEciWcXWaSrElrkn5/79AD/fy/zjO47zKEo KBf6uQurXv+RCT3uwDU5QowVoYuanwo= =5+1V -----END PGP SIGNATURE----- Merge tag 'i2c-host-7.1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux into i2c/for-mergewindow i2c-host for v7.1, part 2 - cx92755: convert I2C bindings to DT schema - mediatek: add optional bus power management during transfers - pxa: handle early bus busy condition
This commit is contained in:
commit
d891635322
49
Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml
Normal file
49
Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/i2c/cnxt,cx92755-i2c.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Conexant Digicolor I2C controller
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/i2c/i2c-controller.yaml#
|
||||
|
||||
maintainers:
|
||||
- Baruch Siach <baruch@tkos.co.il>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: cnxt,cx92755-i2c
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-frequency:
|
||||
default: 100000
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c@f0000120 {
|
||||
compatible = "cnxt,cx92755-i2c";
|
||||
reg = <0xf0000120 0x10>;
|
||||
interrupts = <28>;
|
||||
clocks = <&main_clk>;
|
||||
clock-frequency = <100000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
Conexant Digicolor I2C controller
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "cnxt,cx92755-i2c"
|
||||
- reg: physical address and length of the device registers
|
||||
- interrupts: a single interrupt specifier
|
||||
- clocks: clock for the device
|
||||
- #address-cells: should be <1>
|
||||
- #size-cells: should be <0>
|
||||
|
||||
Optional properties:
|
||||
- clock-frequency: the desired I2C bus clock frequency in Hz; in
|
||||
absence of this property the default value is used (100 kHz).
|
||||
|
||||
Example:
|
||||
|
||||
i2c: i2c@f0000120 {
|
||||
compatible = "cnxt,cx92755-i2c";
|
||||
reg = <0xf0000120 0x10>;
|
||||
interrupts = <28>;
|
||||
clocks = <&main_clk>;
|
||||
clock-frequency = <100000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -1244,9 +1245,15 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
|||
bool write_then_read_en = false;
|
||||
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
|
||||
|
||||
if (i2c->adap.bus_regulator) {
|
||||
ret = regulator_enable(i2c->adap.bus_regulator);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_regulator;
|
||||
|
||||
i2c->auto_restart = i2c->dev_comp->auto_restart;
|
||||
|
||||
|
|
@ -1301,6 +1308,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
|||
|
||||
err_exit:
|
||||
clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||||
err_regulator:
|
||||
if (i2c->adap.bus_regulator)
|
||||
regulator_disable(i2c->adap.bus_regulator);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
#define ISR_GCAD (1 << 8) /* general call address detected */
|
||||
#define ISR_SAD (1 << 9) /* slave address detected */
|
||||
#define ISR_BED (1 << 10) /* bus error no ACK/NAK */
|
||||
#define ISR_A3700_EBB (1 << 11) /* early bus busy for armada 3700 */
|
||||
|
||||
#define ILCR_SLV_SHIFT 0
|
||||
#define ILCR_SLV_MASK (0x1FF << ILCR_SLV_SHIFT)
|
||||
|
|
@ -263,6 +264,7 @@ struct pxa_i2c {
|
|||
bool highmode_enter;
|
||||
u32 fm_mask;
|
||||
u32 hs_mask;
|
||||
u32 busy_mask;
|
||||
|
||||
struct i2c_bus_recovery_info recovery;
|
||||
struct pinctrl *pinctrl;
|
||||
|
|
@ -430,7 +432,7 @@ static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
|
|||
|
||||
while (1) {
|
||||
isr = readl(_ISR(i2c));
|
||||
if (!(isr & (ISR_IBB | ISR_UB)))
|
||||
if (!(isr & i2c->busy_mask))
|
||||
return 0;
|
||||
|
||||
if (isr & ISR_SAD)
|
||||
|
|
@ -467,7 +469,7 @@ static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
|
|||
* quick check of the i2c lines themselves to ensure they've
|
||||
* gone high...
|
||||
*/
|
||||
if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 &&
|
||||
if ((readl(_ISR(i2c)) & i2c->busy_mask) == 0 &&
|
||||
readl(_IBMR(i2c)) == (IBMR_SCLS | IBMR_SDAS)) {
|
||||
if (i2c_debug > 0)
|
||||
dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
|
||||
|
|
@ -488,7 +490,7 @@ static int i2c_pxa_set_master(struct pxa_i2c *i2c)
|
|||
if (i2c_debug)
|
||||
dev_dbg(&i2c->adap.dev, "setting to bus master\n");
|
||||
|
||||
if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) != 0) {
|
||||
if ((readl(_ISR(i2c)) & i2c->busy_mask) != 0) {
|
||||
dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
|
||||
if (!i2c_pxa_wait_master(i2c)) {
|
||||
dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
|
||||
|
|
@ -514,7 +516,7 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
|
|||
dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
|
||||
__func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
|
||||
|
||||
if ((readl(_ISR(i2c)) & (ISR_UB|ISR_IBB)) == 0 ||
|
||||
if ((readl(_ISR(i2c)) & i2c->busy_mask) == 0 ||
|
||||
(readl(_ISR(i2c)) & ISR_SAD) != 0 ||
|
||||
(readl(_ICR(i2c)) & ICR_SCLE) == 0) {
|
||||
if (i2c_debug > 1)
|
||||
|
|
@ -1177,7 +1179,7 @@ static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
|
|||
/*
|
||||
* Wait for the bus to become free.
|
||||
*/
|
||||
while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB))
|
||||
while (timeout-- && readl(_ISR(i2c)) & i2c->busy_mask)
|
||||
udelay(1000);
|
||||
|
||||
if (timeout < 0) {
|
||||
|
|
@ -1322,7 +1324,7 @@ static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap)
|
|||
* handing control of the bus back to avoid the bus changing state.
|
||||
*/
|
||||
isr = readl(_ISR(i2c));
|
||||
if (isr & (ISR_UB | ISR_IBB)) {
|
||||
if (isr & i2c->busy_mask) {
|
||||
dev_dbg(&i2c->adap.dev,
|
||||
"recovery: resetting controller, ISR=0x%08x\n", isr);
|
||||
i2c_pxa_do_reset(i2c);
|
||||
|
|
@ -1479,6 +1481,10 @@ static int i2c_pxa_probe(struct platform_device *dev)
|
|||
i2c->fm_mask = pxa_reg_layout[i2c_type].fm;
|
||||
i2c->hs_mask = pxa_reg_layout[i2c_type].hs;
|
||||
|
||||
i2c->busy_mask = ISR_UB | ISR_IBB;
|
||||
if (i2c_type == REGS_A3700)
|
||||
i2c->busy_mask |= ISR_A3700_EBB;
|
||||
|
||||
if (i2c_type != REGS_CE4100)
|
||||
i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user