Commit 3265568d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c/for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:
 "I2C has mostly driver updates this time.

  The few noteworthy changes are: the core has now support for analog
  and digital filters with at91 being the first user, a core addition to
  replace the NULL returning i2c_new_probed_device() with an ERR_PTR
  variant, and the pxa driver has finally being moved to use the generic
  I2C slave interface. We have quite a significant number of reviews per
  patch this time, so thank you to all involved!"

* 'i2c/for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (37 commits)
  video: fbdev: matrox: convert to i2c_new_scanned_device
  i2c: icy: convert to i2c_new_scanned_device
  i2c: replace i2c_new_probed_device with an ERR_PTR variant
  i2c: Fix Kconfig indentation
  i2c: smbus: Don't filter out duplicate alerts
  i2c: i801: Correct Intel Jasper Lake SOC naming
  i2c: i2c-stm32f7: fix 10-bits check in slave free id search loop
  i2c: iproc: Add i2c repeated start capability
  i2c: remove helpers for ref-counting clients
  i2c: tegra: Use dma_request_chan() directly for channel request
  i2c: sh_mobile: Use dma_request_chan() directly for channel request
  i2c: qup: Use dma_request_chan() directly for channel request
  i2c: at91: Use dma_request_chan() directly for channel request
  i2c: rcar: Remove superfluous call to clk_get_rate()
  i2c: pxa: remove unused i2c-slave APIs
  i2c: pxa: migrate to new i2c_slave APIs
  i2c: cros-ec-tunnel: Make the device acpi compatible
  i2c: stm32f7: report dma error during probe
  i2c: icy: no need to populate address for scanned device
  i2c: xiic: Fix kerneldoc warnings
  ...
parents 31764f1b a72e27f7
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2019 BayLibre, SAS
%YAML 1.2
---
$id: "http://devicetree.org/schemas/i2c/amlogic,meson6-i2c.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Amlogic Meson I2C Controller
maintainers:
- Neil Armstrong <narmstrong@baylibre.com>
- Beniamino Galvani <b.galvani@gmail.com>
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
enum:
- amlogic,meson6-i2c # Meson6, Meson8 and compatible SoCs
- amlogic,meson-gxbb-i2c # GXBB and compatible SoCs
- amlogic,meson-axg-i2c # AXG and compatible SoCs
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
minItems: 1
required:
- compatible
- reg
- interrupts
- clocks
examples:
- |
i2c@c8100500 {
compatible = "amlogic,meson6-i2c";
reg = <0xc8100500 0x20>;
interrupts = <92>;
clocks = <&clk81>;
#address-cells = <1>;
#size-cells = <0>;
eeprom@52 {
compatible = "atmel,24c32";
reg = <0x52>;
};
};
Device tree configuration for the I2C busses on the AST24XX and AST25XX SoCs. Device tree configuration for the I2C busses on the AST24XX, AST25XX, and AST26XX SoCs.
Required Properties: Required Properties:
- #address-cells : should be 1 - #address-cells : should be 1
...@@ -6,6 +6,7 @@ Required Properties: ...@@ -6,6 +6,7 @@ Required Properties:
- reg : address offset and range of bus - reg : address offset and range of bus
- compatible : should be "aspeed,ast2400-i2c-bus" - compatible : should be "aspeed,ast2400-i2c-bus"
or "aspeed,ast2500-i2c-bus" or "aspeed,ast2500-i2c-bus"
or "aspeed,ast2600-i2c-bus"
- clocks : root clock of bus, should reference the APB - clocks : root clock of bus, should reference the APB
clock in the second cell clock in the second cell
- resets : phandle to reset controller with the reset number in - resets : phandle to reset controller with the reset number in
......
...@@ -3,7 +3,8 @@ I2C for Atmel platforms ...@@ -3,7 +3,8 @@ I2C for Atmel platforms
Required properties : Required properties :
- compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c", - compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c",
"atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c", "atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c",
"atmel,at91sam9x5-i2c", "atmel,sama5d4-i2c" or "atmel,sama5d2-i2c" "atmel,at91sam9x5-i2c", "atmel,sama5d4-i2c", "atmel,sama5d2-i2c" or
"microchip,sam9x60-i2c"
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
- interrupts: interrupt number to the cpu. - interrupts: interrupt number to the cpu.
......
Amlogic Meson I2C controller
Required properties:
- compatible: must be:
"amlogic,meson6-i2c" for Meson8 and compatible SoCs
"amlogic,meson-gxbb-i2c" for GXBB and compatible SoCs
"amlogic,meson-axg-i2c"for AXG and compatible SoCs
- 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>
For details regarding the following core I2C bindings see also i2c.txt.
Optional properties:
- clock-frequency: the desired I2C bus clock frequency in Hz; in
absence of this property the default value is used (100 kHz).
Examples:
i2c@c8100500 {
compatible = "amlogic,meson6-i2c";
reg = <0xc8100500 0x20>;
interrupts = <0 92 1>;
clocks = <&clk81>;
#address-cells = <1>;
#size-cells = <0>;
};
...@@ -55,6 +55,24 @@ wants to support one of the below features, it should adapt the bindings below. ...@@ -55,6 +55,24 @@ wants to support one of the below features, it should adapt the bindings below.
Number of nanoseconds the SDA signal takes to fall; t(f) in the I2C Number of nanoseconds the SDA signal takes to fall; t(f) in the I2C
specification. specification.
- i2c-analog-filter
Enable analog filter for i2c lines.
- i2c-digital-filter
Enable digital filter for i2c lines.
- i2c-digital-filter-width-ns
Width of spikes which can be filtered by digital filter
(i2c-digital-filter). This width is specified in nanoseconds.
- i2c-analog-filter-cutoff-frequency
Frequency that the analog filter (i2c-analog-filter) uses to distinguish
which signal to filter. Signal with higher frequency than specified will
be filtered out. Only lower frequency will pass (this is applicable to
a low-pass analog filter). Typical value should be above the normal
i2c bus clock frequency (clock-frequency).
Specified in Hz.
- interrupts - interrupts
interrupts used by the device. interrupts used by the device.
......
...@@ -7,6 +7,7 @@ Required properties: ...@@ -7,6 +7,7 @@ Required properties:
"renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC. "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC.
"renesas,i2c-r8a77470" if the device is a part of a R8A77470 SoC. "renesas,i2c-r8a77470" if the device is a part of a R8A77470 SoC.
"renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC. "renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC.
"renesas,i2c-r8a774b1" if the device is a part of a R8A774B1 SoC.
"renesas,i2c-r8a774c0" if the device is a part of a R8A774C0 SoC. "renesas,i2c-r8a774c0" if the device is a part of a R8A774C0 SoC.
"renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC. "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC.
"renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC. "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC.
......
...@@ -8,6 +8,7 @@ Required properties: ...@@ -8,6 +8,7 @@ Required properties:
- "renesas,iic-r8a7744" (RZ/G1N) - "renesas,iic-r8a7744" (RZ/G1N)
- "renesas,iic-r8a7745" (RZ/G1E) - "renesas,iic-r8a7745" (RZ/G1E)
- "renesas,iic-r8a774a1" (RZ/G2M) - "renesas,iic-r8a774a1" (RZ/G2M)
- "renesas,iic-r8a774b1" (RZ/G2N)
- "renesas,iic-r8a774c0" (RZ/G2E) - "renesas,iic-r8a774c0" (RZ/G2E)
- "renesas,iic-r8a7790" (R-Car H2) - "renesas,iic-r8a7790" (R-Car H2)
- "renesas,iic-r8a7791" (R-Car M2-W) - "renesas,iic-r8a7791" (R-Car M2-W)
......
...@@ -42,6 +42,7 @@ Supported adapters: ...@@ -42,6 +42,7 @@ Supported adapters:
* Intel Comet Lake (PCH) * Intel Comet Lake (PCH)
* Intel Elkhart Lake (PCH) * Intel Elkhart Lake (PCH)
* Intel Tiger Lake (PCH) * Intel Tiger Lake (PCH)
* Intel Jasper Lake (SOC)
Datasheets: Publicly available at the Intel website Datasheets: Publicly available at the Intel website
......
...@@ -123,7 +123,7 @@ present or not (for example for an optional feature which is not present ...@@ -123,7 +123,7 @@ present or not (for example for an optional feature which is not present
on cheap variants of a board but you have no way to tell them apart), or on cheap variants of a board but you have no way to tell them apart), or
it may have different addresses from one board to the next (manufacturer it may have different addresses from one board to the next (manufacturer
changing its design without notice). In this case, you can call changing its design without notice). In this case, you can call
i2c_new_probed_device() instead of i2c_new_device(). i2c_new_scanned_device() instead of i2c_new_device().
Example (from the nxp OHCI driver):: Example (from the nxp OHCI driver)::
...@@ -139,8 +139,8 @@ Example (from the nxp OHCI driver):: ...@@ -139,8 +139,8 @@ Example (from the nxp OHCI driver)::
i2c_adap = i2c_get_adapter(2); i2c_adap = i2c_get_adapter(2);
memset(&i2c_info, 0, sizeof(struct i2c_board_info)); memset(&i2c_info, 0, sizeof(struct i2c_board_info));
strscpy(i2c_info.type, "isp1301_nxp", sizeof(i2c_info.type)); strscpy(i2c_info.type, "isp1301_nxp", sizeof(i2c_info.type));
isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, isp1301_i2c_client = i2c_new_scanned_device(i2c_adap, &i2c_info,
normal_i2c, NULL); normal_i2c, NULL);
i2c_put_adapter(i2c_adap); i2c_put_adapter(i2c_adap);
(...) (...)
} }
...@@ -153,14 +153,14 @@ simply gives up. ...@@ -153,14 +153,14 @@ simply gives up.
The driver which instantiated the I2C device is responsible for destroying The driver which instantiated the I2C device is responsible for destroying
it on cleanup. This is done by calling i2c_unregister_device() on the it on cleanup. This is done by calling i2c_unregister_device() on the
pointer that was earlier returned by i2c_new_device() or pointer that was earlier returned by i2c_new_device() or
i2c_new_probed_device(). i2c_new_scanned_device().
Method 3: Probe an I2C bus for certain devices Method 3: Probe an I2C bus for certain devices
---------------------------------------------- ----------------------------------------------
Sometimes you do not have enough information about an I2C device, not even Sometimes you do not have enough information about an I2C device, not even
to call i2c_new_probed_device(). The typical case is hardware monitoring to call i2c_new_scanned_device(). The typical case is hardware monitoring
chips on PC mainboards. There are several dozen models, which can live chips on PC mainboards. There are several dozen models, which can live
at 25 different addresses. Given the huge number of mainboards out there, at 25 different addresses. Given the huge number of mainboards out there,
it is next to impossible to build an exhaustive list of the hardware it is next to impossible to build an exhaustive list of the hardware
......
...@@ -185,14 +185,14 @@ Sometimes you know that a device is connected to a given I2C bus, but you ...@@ -185,14 +185,14 @@ Sometimes you know that a device is connected to a given I2C bus, but you
don't know the exact address it uses. This happens on TV adapters for don't know the exact address it uses. This happens on TV adapters for
example, where the same driver supports dozens of slightly different example, where the same driver supports dozens of slightly different
models, and I2C device addresses change from one model to the next. In models, and I2C device addresses change from one model to the next. In
that case, you can use the i2c_new_probed_device() variant, which is that case, you can use the i2c_new_scanned_device() variant, which is
similar to i2c_new_device(), except that it takes an additional list of similar to i2c_new_device(), except that it takes an additional list of
possible I2C addresses to probe. A device is created for the first possible I2C addresses to probe. A device is created for the first
responsive address in the list. If you expect more than one device to be responsive address in the list. If you expect more than one device to be
present in the address range, simply call i2c_new_probed_device() that present in the address range, simply call i2c_new_scanned_device() that
many times. many times.
The call to i2c_new_device() or i2c_new_probed_device() typically happens The call to i2c_new_device() or i2c_new_scanned_device() typically happens
in the I2C bus driver. You may want to save the returned i2c_client in the I2C bus driver. You may want to save the returned i2c_client
reference for later use. reference for later use.
...@@ -237,7 +237,7 @@ Device Deletion ...@@ -237,7 +237,7 @@ Device Deletion
--------------- ---------------
Each I2C device which has been created using i2c_new_device() or Each I2C device which has been created using i2c_new_device() or
i2c_new_probed_device() can be unregistered by calling i2c_new_scanned_device() can be unregistered by calling
i2c_unregister_device(). If you don't call it explicitly, it will be i2c_unregister_device(). If you don't call it explicitly, it will be
called automatically before the underlying I2C bus itself is removed, as a called automatically before the underlying I2C bus itself is removed, as a
device can't survive its parent in the device driver model. device can't survive its parent in the device driver model.
......
...@@ -145,6 +145,7 @@ config I2C_I801 ...@@ -145,6 +145,7 @@ config I2C_I801
Comet Lake (PCH) Comet Lake (PCH)
Elkhart Lake (PCH) Elkhart Lake (PCH)
Tiger Lake (PCH) Tiger Lake (PCH)
Jasper Lake (SOC)
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-i801. will be called i2c-i801.
...@@ -292,7 +293,7 @@ config I2C_VIA ...@@ -292,7 +293,7 @@ config I2C_VIA
select I2C_ALGOBIT select I2C_ALGOBIT
help help
If you say yes to this option, support will be included for the VIA If you say yes to this option, support will be included for the VIA
82C586B I2C interface 82C586B I2C interface
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-via. will be called i2c-via.
...@@ -677,11 +678,11 @@ config I2C_IMX_LPI2C ...@@ -677,11 +678,11 @@ config I2C_IMX_LPI2C
tristate "IMX Low Power I2C interface" tristate "IMX Low Power I2C interface"
depends on ARCH_MXC || COMPILE_TEST depends on ARCH_MXC || COMPILE_TEST
help help
Say Y here if you want to use the Low Power IIC bus controller Say Y here if you want to use the Low Power IIC bus controller
on the Freescale i.MX processors. on the Freescale i.MX processors.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-imx-lpi2c. will be called i2c-imx-lpi2c.
config I2C_IOP3XX config I2C_IOP3XX
tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface" tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
...@@ -874,6 +875,7 @@ config I2C_PXA_PCI ...@@ -874,6 +875,7 @@ config I2C_PXA_PCI
config I2C_PXA_SLAVE config I2C_PXA_SLAVE
bool "Intel PXA2XX I2C Slave comms support" bool "Intel PXA2XX I2C Slave comms support"
depends on I2C_PXA && !X86_32 depends on I2C_PXA && !X86_32
select I2C_SLAVE
help help
Support I2C slave mode communications on the PXA I2C bus. This Support I2C slave mode communications on the PXA I2C bus. This
is necessary for systems where the PXA may be a target on the is necessary for systems where the PXA may be a target on the
...@@ -1182,9 +1184,9 @@ config I2C_DIOLAN_U2C ...@@ -1182,9 +1184,9 @@ config I2C_DIOLAN_U2C
will be called i2c-diolan-u2c. will be called i2c-diolan-u2c.
config I2C_DLN2 config I2C_DLN2
tristate "Diolan DLN-2 USB I2C adapter" tristate "Diolan DLN-2 USB I2C adapter"
depends on MFD_DLN2 depends on MFD_DLN2
help help
If you say yes to this option, support will be included for Diolan If you say yes to this option, support will be included for Diolan
DLN2, a USB to I2C interface. DLN2, a USB to I2C interface.
...@@ -1283,9 +1285,9 @@ config I2C_VIPERBOARD ...@@ -1283,9 +1285,9 @@ config I2C_VIPERBOARD
help help
Say yes here to access the I2C part of the Nano River Say yes here to access the I2C part of the Nano River
Technologies Viperboard as I2C master. Technologies Viperboard as I2C master.
See viperboard API specification and Nano See viperboard API specification and Nano
River Tech's viperboard.h for detailed meaning River Tech's viperboard.h for detailed meaning
of the module parameters. of the module parameters.
comment "Other I2C/SMBus bus drivers" comment "Other I2C/SMBus bus drivers"
......
...@@ -952,6 +952,10 @@ static const struct of_device_id aspeed_i2c_bus_of_table[] = { ...@@ -952,6 +952,10 @@ static const struct of_device_id aspeed_i2c_bus_of_table[] = {
.compatible = "aspeed,ast2500-i2c-bus", .compatible = "aspeed,ast2500-i2c-bus",
.data = aspeed_i2c_25xx_get_clk_reg_val, .data = aspeed_i2c_25xx_get_clk_reg_val,
}, },
{
.compatible = "aspeed,ast2600-i2c-bus",
.data = aspeed_i2c_25xx_get_clk_reg_val,
},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, aspeed_i2c_bus_of_table); MODULE_DEVICE_TABLE(of, aspeed_i2c_bus_of_table);
......
...@@ -68,6 +68,9 @@ static struct at91_twi_pdata at91rm9200_config = { ...@@ -68,6 +68,9 @@ static struct at91_twi_pdata at91rm9200_config = {
.has_unre_flag = true, .has_unre_flag = true,
.has_alt_cmd = false, .has_alt_cmd = false,
.has_hold_field = false, .has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
}; };
static struct at91_twi_pdata at91sam9261_config = { static struct at91_twi_pdata at91sam9261_config = {
...@@ -76,6 +79,9 @@ static struct at91_twi_pdata at91sam9261_config = { ...@@ -76,6 +79,9 @@ static struct at91_twi_pdata at91sam9261_config = {
.has_unre_flag = false, .has_unre_flag = false,
.has_alt_cmd = false, .has_alt_cmd = false,
.has_hold_field = false, .has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
}; };
static struct at91_twi_pdata at91sam9260_config = { static struct at91_twi_pdata at91sam9260_config = {
...@@ -84,6 +90,9 @@ static struct at91_twi_pdata at91sam9260_config = { ...@@ -84,6 +90,9 @@ static struct at91_twi_pdata at91sam9260_config = {
.has_unre_flag = false, .has_unre_flag = false,
.has_alt_cmd = false, .has_alt_cmd = false,
.has_hold_field = false, .has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
}; };
static struct at91_twi_pdata at91sam9g20_config = { static struct at91_twi_pdata at91sam9g20_config = {
...@@ -92,6 +101,9 @@ static struct at91_twi_pdata at91sam9g20_config = { ...@@ -92,6 +101,9 @@ static struct at91_twi_pdata at91sam9g20_config = {
.has_unre_flag = false, .has_unre_flag = false,
.has_alt_cmd = false, .has_alt_cmd = false,
.has_hold_field = false, .has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
}; };
static struct at91_twi_pdata at91sam9g10_config = { static struct at91_twi_pdata at91sam9g10_config = {
...@@ -100,6 +112,9 @@ static struct at91_twi_pdata at91sam9g10_config = { ...@@ -100,6 +112,9 @@ static struct at91_twi_pdata at91sam9g10_config = {
.has_unre_flag = false, .has_unre_flag = false,
.has_alt_cmd = false, .has_alt_cmd = false,
.has_hold_field = false, .has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
}; };
static const struct platform_device_id at91_twi_devtypes[] = { static const struct platform_device_id at91_twi_devtypes[] = {
...@@ -130,6 +145,9 @@ static struct at91_twi_pdata at91sam9x5_config = { ...@@ -130,6 +145,9 @@ static struct at91_twi_pdata at91sam9x5_config = {
.has_unre_flag = false, .has_unre_flag = false,
.has_alt_cmd = false, .has_alt_cmd = false,
.has_hold_field = false, .has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
}; };
static struct at91_twi_pdata sama5d4_config = { static struct at91_twi_pdata sama5d4_config = {
...@@ -138,6 +156,9 @@ static struct at91_twi_pdata sama5d4_config = { ...@@ -138,6 +156,9 @@ static struct at91_twi_pdata sama5d4_config = {
.has_unre_flag = false, .has_unre_flag = false,
.has_alt_cmd = false, .has_alt_cmd = false,
.has_hold_field = true, .has_hold_field = true,
.has_dig_filtr = true,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
}; };
static struct at91_twi_pdata sama5d2_config = { static struct at91_twi_pdata sama5d2_config = {
...@@ -146,6 +167,20 @@ static struct at91_twi_pdata sama5d2_config = { ...@@ -146,6 +167,20 @@ static struct at91_twi_pdata sama5d2_config = {
.has_unre_flag = true, .has_unre_flag = true,
.has_alt_cmd = true, .has_alt_cmd = true,
.has_hold_field = true, .has_hold_field = true,
.has_dig_filtr = true,
.has_adv_dig_filtr = true,
.has_ana_filtr = true,
};
static struct at91_twi_pdata sam9x60_config = {
.clk_max_div = 7,
.clk_offset = 4,
.has_unre_flag = true,
.has_alt_cmd = true,
.has_hold_field = true,
.has_dig_filtr = true,
.has_adv_dig_filtr = true,
.has_ana_filtr = true,
}; };
static const struct of_device_id atmel_twi_dt_ids[] = { static const struct of_device_id atmel_twi_dt_ids[] = {
...@@ -173,6 +208,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = { ...@@ -173,6 +208,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = {
}, { }, {
.compatible = "atmel,sama5d2-i2c", .compatible = "atmel,sama5d2-i2c",
.data = &sama5d2_config, .data = &sama5d2_config,
}, {
.compatible = "microchip,sam9x60-i2c",
.data = &sam9x60_config,
}, { }, {
/* sentinel */ /* sentinel */
} }
......
...@@ -31,12 +31,32 @@ ...@@ -31,12 +31,32 @@
void at91_init_twi_bus_master(struct at91_twi_dev *dev) void at91_init_twi_bus_master(struct at91_twi_dev *dev)
{ {
struct at91_twi_pdata *pdata = dev->pdata;
u32 filtr = 0;
/* FIFO should be enabled immediately after the software reset */ /* FIFO should be enabled immediately after the software reset */
if (dev->fifo_size) if (dev->fifo_size)
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_FIFOEN); at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_FIFOEN);
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN); at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN);
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS); at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS);
at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg); at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg);
/* enable digital filter */
if (pdata->has_dig_filtr && dev->enable_dig_filt)
filtr |= AT91_TWI_FILTR_FILT;
/* enable advanced digital filter */
if (pdata->has_adv_dig_filtr && dev->enable_dig_filt)
filtr |= AT91_TWI_FILTR_FILT |
(AT91_TWI_FILTR_THRES(dev->filter_width) &
AT91_TWI_FILTR_THRES_MASK);
/* enable analog filter */
if (pdata->has_ana_filtr && dev->enable_ana_filt)
filtr |= AT91_TWI_FILTR_PADFEN;
if (filtr)
at91_twi_write(dev, AT91_TWI_FILTR, filtr);
} }
/* /*
...@@ -45,7 +65,7 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev) ...@@ -45,7 +65,7 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev)
*/ */
static void at91_calc_twi_clock(struct at91_twi_dev *dev) static void at91_calc_twi_clock(struct at91_twi_dev *dev)
{ {
int ckdiv, cdiv, div, hold = 0; int ckdiv, cdiv, div, hold = 0, filter_width = 0;
struct at91_twi_pdata *pdata = dev->pdata; struct at91_twi_pdata *pdata = dev->pdata;
int offset = pdata->clk_offset; int offset = pdata->clk_offset;
int max_ckdiv = pdata->clk_max_div; int max_ckdiv = pdata->clk_max_div;
...@@ -84,11 +104,29 @@ static void at91_calc_twi_clock(struct at91_twi_dev *dev) ...@@ -84,11 +104,29 @@ static void at91_calc_twi_clock(struct at91_twi_dev *dev)
} }
} }
if (pdata->has_adv_dig_filtr) {
/*
* filter width = 0 to AT91_TWI_FILTR_THRES_MAX
* peripheral clocks
*/
filter_width = DIV_ROUND_UP(t->digital_filter_width_ns
* (clk_get_rate(dev->clk) / 1000), 1000000);
if (filter_width > AT91_TWI_FILTR_THRES_MAX) {
dev_warn(dev->dev,
"Filter threshold set to its maximum value (%d instead of %d)\n",
AT91_TWI_FILTR_THRES_MAX, filter_width);
filter_width = AT91_TWI_FILTR_THRES_MAX;
}
}
dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv
| AT91_TWI_CWGR_HOLD(hold); | AT91_TWI_CWGR_HOLD(hold);
dev_dbg(dev->dev, "cdiv %d ckdiv %d hold %d (%d ns)\n", dev->filter_width = filter_width;
cdiv, ckdiv, hold, t->sda_hold_ns);
dev_dbg(dev->dev, "cdiv %d ckdiv %d hold %d (%d ns), filter_width %d (%d ns)\n",
cdiv, ckdiv, hold, t->sda_hold_ns, filter_width,
t->digital_filter_width_ns);
} }
static void at91_twi_dma_cleanup(struct at91_twi_dev *dev) static void at91_twi_dma_cleanup(struct at91_twi_dev *dev)
...@@ -720,14 +758,14 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) ...@@ -720,14 +758,14 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)
slave_config.dst_maxburst = 1; slave_config.dst_maxburst = 1;
slave_config.device_fc = false; slave_config.device_fc = false;
dma->chan_tx = dma_request_slave_channel_reason(dev->dev, "tx"); dma->chan_tx = dma_request_chan(dev->dev, "tx");
if (IS_ERR(dma->chan_tx)) { if (IS_ERR(dma->chan_tx)) {
ret = PTR_ERR(dma->chan_tx); ret = PTR_ERR(dma->chan_tx);
dma->chan_tx = NULL; dma->chan_tx = NULL;
goto error; goto error;
} }
dma->chan_rx = dma_request_slave_channel_reason(dev->dev, "rx"); dma->chan_rx = dma_request_chan(dev->dev, "rx");
if (IS_ERR(dma->chan_rx)) { if (IS_ERR(dma->chan_rx)) {
ret = PTR_ERR(dma->chan_rx); ret = PTR_ERR(dma->chan_rx);
dma->chan_rx = NULL; dma->chan_rx = NULL;
...@@ -793,6 +831,11 @@ int at91_twi_probe_master(struct platform_device *pdev, ...@@ -793,6 +831,11 @@ int at91_twi_probe_master(struct platform_device *pdev,
dev_info(dev->dev, "Using FIFO (%u data)\n", dev->fifo_size); dev_info(dev->dev, "Using FIFO (%u data)\n", dev->fifo_size);
} }
dev->enable_dig_filt = of_property_read_bool(pdev->dev.of_node,
"i2c-digital-filter");
dev->enable_ana_filt = of_property_read_bool(pdev->dev.of_node,
"i2c-analog-filter");
at91_calc_twi_clock(dev); at91_calc_twi_clock(dev);
dev->adapter.algo = &at91_twi_algorithm; dev->adapter.algo = &at91_twi_algorithm;
......
...@@ -84,6 +84,13 @@ ...@@ -84,6 +84,13 @@
#define AT91_TWI_ACR_DATAL(len) ((len) & 0xff) #define AT91_TWI_ACR_DATAL(len) ((len) & 0xff)
#define AT91_TWI_ACR_DIR BIT(8) #define AT91_TWI_ACR_DIR BIT(8)
#define AT91_TWI_FILTR 0x0044
#define AT91_TWI_FILTR_FILT BIT(0)
#define AT91_TWI_FILTR_PADFEN BIT(1)
#define AT91_TWI_FILTR_THRES(v) ((v) << 8)
#define AT91_TWI_FILTR_THRES_MAX 7
#define AT91_TWI_FILTR_THRES_MASK GENMASK(10, 8)
#define AT91_TWI_FMR 0x0050 /* FIFO Mode Register */ #define AT91_TWI_FMR 0x0050 /* FIFO Mode Register */
#define AT91_TWI_FMR_TXRDYM(mode) (((mode) & 0x3) << 0) #define AT91_TWI_FMR_TXRDYM(mode) (((mode) & 0x3) << 0)
#define AT91_TWI_FMR_TXRDYM_MASK (0x3 << 0) #define AT91_TWI_FMR_TXRDYM_MASK (0x3 << 0)
...@@ -108,6 +115,9 @@ struct at91_twi_pdata { ...@@ -108,6 +115,9 @@ struct at91_twi_pdata {
bool has_unre_flag; bool has_unre_flag;
bool has_alt_cmd; bool has_alt_cmd;
bool has_hold_field; bool has_hold_field;
bool has_dig_filtr;
bool has_adv_dig_filtr;
bool has_ana_filtr;
struct at_dma_slave dma_slave; struct at_dma_slave dma_slave;
}; };
...@@ -145,6 +155,9 @@ struct at91_twi_dev { ...@@ -145,6 +155,9 @@ struct at91_twi_dev {
unsigned smr; unsigned smr;
struct i2c_client *slave; struct i2c_client *slave;
#endif #endif
bool enable_dig_filt;
bool enable_ana_filt;
u32 filter_width;
}; };
unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg); unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg);
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
#define M_CMD_PROTOCOL_MASK 0xf #define M_CMD_PROTOCOL_MASK 0xf
#define M_CMD_PROTOCOL_BLK_WR 0x7 #define M_CMD_PROTOCOL_BLK_WR 0x7
#define M_CMD_PROTOCOL_BLK_RD 0x8 #define M_CMD_PROTOCOL_BLK_RD 0x8
#define M_CMD_PROTOCOL_PROCESS 0xa
#define M_CMD_PEC_SHIFT 8 #define M_CMD_PEC_SHIFT 8
#define M_CMD_RD_CNT_SHIFT 0 #define M_CMD_RD_CNT_SHIFT 0
#define M_CMD_RD_CNT_MASK 0xff #define M_CMD_RD_CNT_MASK 0xff
...@@ -675,13 +676,20 @@ static int bcm_iproc_i2c_xfer_wait(struct bcm_iproc_i2c_dev *iproc_i2c, ...@@ -675,13 +676,20 @@ static int bcm_iproc_i2c_xfer_wait(struct bcm_iproc_i2c_dev *iproc_i2c,
return 0; return 0;
} }
static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, /*
struct i2c_msg *msg) * If 'process_call' is true, then this is a multi-msg transfer that requires
* a repeated start between the messages.
* More specifically, it must be a write (reg) followed by a read (data).
* The i2c quirks are set to enforce this rule.
*/
static int bcm_iproc_i2c_xfer_internal(struct bcm_iproc_i2c_dev *iproc_i2c,
struct i2c_msg *msgs, bool process_call)
{ {
int i; int i;
u8 addr; u8 addr;
u32 val, tmp, val_intr_en; u32 val, tmp, val_intr_en;
unsigned int tx_bytes; unsigned int tx_bytes;
struct i2c_msg *msg = &msgs[0];
/* check if bus is busy */ /* check if bus is busy */
if (!!(iproc_i2c_rd_reg(iproc_i2c, if (!!(iproc_i2c_rd_reg(iproc_i2c,
...@@ -707,14 +715,29 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, ...@@ -707,14 +715,29 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
val = msg->buf[i]; val = msg->buf[i];
/* mark the last byte */ /* mark the last byte */
if (i == msg->len - 1) if (!process_call && (i == msg->len - 1))
val |= BIT(M_TX_WR_STATUS_SHIFT); val |= 1 << M_TX_WR_STATUS_SHIFT;
iproc_i2c_wr_reg(iproc_i2c, M_TX_OFFSET, val); iproc_i2c_wr_reg(iproc_i2c, M_TX_OFFSET, val);
} }
iproc_i2c->tx_bytes = tx_bytes; iproc_i2c->tx_bytes = tx_bytes;
} }
/* Process the read message if this is process call */
if (process_call) {
msg++;
iproc_i2c->msg = msg; /* point to second msg */
/*
* The last byte to be sent out should be a slave
* address with read operation
*/
addr = i2c_8bit_addr_from_msg(msg);
/* mark it the last byte out */
val = addr | (1 << M_TX_WR_STATUS_SHIFT);
iproc_i2c_wr_reg(iproc_i2c, M_TX_OFFSET, val);
}
/* mark as incomplete before starting the transaction */ /* mark as incomplete before starting the transaction */
if (iproc_i2c->irq) if (iproc_i2c->irq)
reinit_completion(&iproc_i2c->done); reinit_completion(&iproc_i2c->done);
...@@ -733,7 +756,7 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, ...@@ -733,7 +756,7 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
* underrun interrupt, which will be triggerred when the TX FIFO is * underrun interrupt, which will be triggerred when the TX FIFO is
* empty. When that happens we can then pump more data into the FIFO * empty. When that happens we can then pump more data into the FIFO
*/ */
if (!(msg->flags & I2C_M_RD) && if (!process_call && !(msg->flags & I2C_M_RD) &&
msg->len > iproc_i2c->tx_bytes) msg->len > iproc_i2c->tx_bytes)
val_intr_en |= BIT(IE_M_TX_UNDERRUN_SHIFT); val_intr_en |= BIT(IE_M_TX_UNDERRUN_SHIFT);
...@@ -743,6 +766,8 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, ...@@ -743,6 +766,8 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
*/ */
val = BIT(M_CMD_START_BUSY_SHIFT); val = BIT(M_CMD_START_BUSY_SHIFT);
if (msg->flags & I2C_M_RD) { if (msg->flags & I2C_M_RD) {
u32 protocol;
iproc_i2c->rx_bytes = 0; iproc_i2c->rx_bytes = 0;
if (msg->len > M_RX_FIFO_MAX_THLD_VALUE) if (msg->len > M_RX_FIFO_MAX_THLD_VALUE)
iproc_i2c->thld_bytes = M_RX_FIFO_THLD_VALUE; iproc_i2c->thld_bytes = M_RX_FIFO_THLD_VALUE;
...@@ -758,7 +783,10 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, ...@@ -758,7 +783,10 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
/* enable the RX threshold interrupt */ /* enable the RX threshold interrupt */
val_intr_en |= BIT(IE_M_RX_THLD_SHIFT); val_intr_en |= BIT(IE_M_RX_THLD_SHIFT);
val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) | protocol = process_call ?
M_CMD_PROTOCOL_PROCESS : M_CMD_PROTOCOL_BLK_RD;
val |= (protocol << M_CMD_PROTOCOL_SHIFT) |
(msg->len << M_CMD_RD_CNT_SHIFT); (msg->len << M_CMD_RD_CNT_SHIFT);
} else { } else {
val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT); val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT);
...@@ -774,17 +802,24 @@ static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter, ...@@ -774,17 +802,24 @@ static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter,
struct i2c_msg msgs[], int num) struct i2c_msg msgs[], int num)
{ {
struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter); struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter);
int ret, i; bool process_call = false;
int ret;
/* go through all messages */ if (num == 2) {
for (i = 0; i < num; i++) { /* Repeated start, use process call */
ret = bcm_iproc_i2c_xfer_single_msg(iproc_i2c, &msgs[i]); process_call = true;
if (ret) { if (msgs[1].flags & I2C_M_NOSTART) {
dev_dbg(iproc_i2c->device, "xfer failed\n"); dev_err(iproc_i2c->device, "Invalid repeated start\n");
return ret; return -EOPNOTSUPP;
} }
} }
ret = bcm_iproc_i2c_xfer_internal(iproc_i2c, msgs, process_call);
if (ret) {
dev_dbg(iproc_i2c->device, "xfer failed\n");
return ret;
}
return num; return num;
} }
...@@ -809,6 +844,8 @@ static struct i2c_algorithm bcm_iproc_algo = { ...@@ -809,6 +844,8 @@ static struct i2c_algorithm bcm_iproc_algo = {
}; };
static const struct i2c_adapter_quirks bcm_iproc_i2c_quirks = { static const struct i2c_adapter_quirks bcm_iproc_i2c_quirks = {
.flags = I2C_AQ_COMB_WRITE_THEN_READ,
.max_comb_1st_msg_len = M_TX_RX_FIFO_SIZE,
.max_read_len = M_RX_MAX_READ_LEN, .max_read_len = M_RX_MAX_READ_LEN,
}; };
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// //
// Copyright (C) 2013 Google, Inc. // Copyright (C) 2013 Google, Inc.
#include <linux/acpi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/platform_data/cros_ec_commands.h> #include <linux/platform_data/cros_ec_commands.h>
...@@ -240,7 +241,6 @@ static const struct i2c_algorithm ec_i2c_algorithm = { ...@@ -240,7 +241,6 @@ static const struct i2c_algorithm ec_i2c_algorithm = {
static int ec_i2c_probe(struct platform_device *pdev) static int ec_i2c_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node;
struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct ec_i2c_device *bus = NULL; struct ec_i2c_device *bus = NULL;
...@@ -256,7 +256,7 @@ static int ec_i2c_probe(struct platform_device *pdev) ...@@ -256,7 +256,7 @@ static int ec_i2c_probe(struct platform_device *pdev)
if (bus == NULL) if (bus == NULL)
return -ENOMEM; return -ENOMEM;
err = of_property_read_u32(np, "google,remote-bus", &remote_bus); err = device_property_read_u32(dev, "google,remote-bus", &remote_bus);
if (err) { if (err) {
dev_err(dev, "Couldn't read remote-bus property\n"); dev_err(dev, "Couldn't read remote-bus property\n");
return err; return err;
...@@ -271,7 +271,7 @@ static int ec_i2c_probe(struct platform_device *pdev) ...@@ -271,7 +271,7 @@ static int ec_i2c_probe(struct platform_device *pdev)
bus->adap.algo = &ec_i2c_algorithm; bus->adap.algo = &ec_i2c_algorithm;
bus->adap.algo_data = bus; bus->adap.algo_data = bus;
bus->adap.dev.parent = &pdev->dev; bus->adap.dev.parent = &pdev->dev;
bus->adap.dev.of_node = np; bus->adap.dev.of_node = pdev->dev.of_node;
bus->adap.retries = I2C_MAX_RETRIES; bus->adap.retries = I2C_MAX_RETRIES;
err = i2c_add_adapter(&bus->adap); err = i2c_add_adapter(&bus->adap);
...@@ -291,19 +291,24 @@ static int ec_i2c_remove(struct platform_device *dev) ...@@ -291,19 +291,24 @@ static int ec_i2c_remove(struct platform_device *dev)
return 0; return 0;
} }
#ifdef CONFIG_OF
static const struct of_device_id cros_ec_i2c_of_match[] = { static const struct of_device_id cros_ec_i2c_of_match[] = {
{ .compatible = "google,cros-ec-i2c-tunnel" }, { .compatible = "google,cros-ec-i2c-tunnel" },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match); MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
#endif
static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] = {
{ "GOOG001A", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_tunnel_acpi_id);
static struct platform_driver ec_i2c_tunnel_driver = { static struct platform_driver ec_i2c_tunnel_driver = {
.probe = ec_i2c_probe, .probe = ec_i2c_probe,
.remove = ec_i2c_remove, .remove = ec_i2c_remove,
.driver = { .driver = {
.name = "cros-ec-i2c-tunnel", .name = "cros-ec-i2c-tunnel",
.acpi_match_table = ACPI_PTR(cros_ec_i2c_tunnel_acpi_id),
.of_match_table = of_match_ptr(cros_ec_i2c_of_match), .of_match_table = of_match_ptr(cros_ec_i2c_of_match),
}, },
}; };
......
...@@ -64,8 +64,10 @@ ...@@ -64,8 +64,10 @@
* Cedar Fork (PCH) 0x18df 32 hard yes yes yes * Cedar Fork (PCH) 0x18df 32 hard yes yes yes
* Ice Lake-LP (PCH) 0x34a3 32 hard yes yes yes * Ice Lake-LP (PCH) 0x34a3 32 hard yes yes yes
* Comet Lake (PCH) 0x02a3 32 hard yes yes yes * Comet Lake (PCH) 0x02a3 32 hard yes yes yes
* Comet Lake-H (PCH) 0x06a3 32 hard yes yes yes
* Elkhart Lake (PCH) 0x4b23 32 hard yes yes yes * Elkhart Lake (PCH) 0x4b23 32 hard yes yes yes
* Tiger Lake-LP (PCH) 0xa0a3 32 hard yes yes yes * Tiger Lake-LP (PCH) 0xa0a3 32 hard yes yes yes
* Jasper Lake (SOC) 0x4da3 32 hard yes yes yes
* *
* Features supported by this driver: * Features supported by this driver:
* Software PEC no * Software PEC no
...@@ -205,6 +207,7 @@ ...@@ -205,6 +207,7 @@
/* Older devices have their ID defined in <linux/pci_ids.h> */ /* Older devices have their ID defined in <linux/pci_ids.h> */
#define PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS 0x02a3 #define PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS 0x02a3
#define PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS 0x06a3
#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12
#define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df #define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df
#define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df #define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df
...@@ -223,6 +226,7 @@ ...@@ -223,6 +226,7 @@
#define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS 0x34a3 #define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS 0x34a3
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
#define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS 0x4b23 #define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS 0x4b23
#define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS 0x4da3
#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2 #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2
...@@ -1069,8 +1073,10 @@ static const struct pci_device_id i801_ids[] = { ...@@ -1069,8 +1073,10 @@ static const struct pci_device_id i801_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS) },
{ 0, } { 0, }
}; };
...@@ -1750,8 +1756,10 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1750,8 +1756,10 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
case PCI_DEVICE_ID_INTEL_CDF_SMBUS: case PCI_DEVICE_ID_INTEL_CDF_SMBUS:
case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS: case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS:
case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS: case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS:
case PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS:
case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS: case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS:
case PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS: case PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS:
case PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS:
priv->features |= FEATURE_BLOCK_PROC; priv->features |= FEATURE_BLOCK_PROC;
priv->features |= FEATURE_I2C_BLOCK_READ; priv->features |= FEATURE_I2C_BLOCK_READ;
priv->features |= FEATURE_IRQ; priv->features |= FEATURE_IRQ;
......
...@@ -122,7 +122,6 @@ static int icy_probe(struct zorro_dev *z, ...@@ -122,7 +122,6 @@ static int icy_probe(struct zorro_dev *z,
struct fwnode_handle *new_fwnode; struct fwnode_handle *new_fwnode;
struct i2c_board_info ltc2990_info = { struct i2c_board_info ltc2990_info = {
.type = "ltc2990", .type = "ltc2990",
.addr = 0x4c,
}; };
i2c = devm_kzalloc(&z->dev, sizeof(*i2c), GFP_KERNEL); i2c = devm_kzalloc(&z->dev, sizeof(*i2c), GFP_KERNEL);
...@@ -188,10 +187,10 @@ static int icy_probe(struct zorro_dev *z, ...@@ -188,10 +187,10 @@ static int icy_probe(struct zorro_dev *z,
ltc2990_info.fwnode = new_fwnode; ltc2990_info.fwnode = new_fwnode;
i2c->ltc2990_client = i2c->ltc2990_client =
i2c_new_probed_device(&i2c->adapter, i2c_new_scanned_device(&i2c->adapter,
&ltc2990_info, &ltc2990_info,
icy_ltc2990_addresses, icy_ltc2990_addresses,
NULL); NULL);
} }
return 0; return 0;
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/i2c-pxa.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -180,7 +179,7 @@ struct pxa_i2c { ...@@ -180,7 +179,7 @@ struct pxa_i2c {
struct i2c_adapter adap; struct i2c_adapter adap;
struct clk *clk; struct clk *clk;
#ifdef CONFIG_I2C_PXA_SLAVE #ifdef CONFIG_I2C_PXA_SLAVE
struct i2c_slave_client *slave; struct i2c_client *slave;
#endif #endif
unsigned int irqlogidx; unsigned int irqlogidx;
...@@ -544,22 +543,23 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr) ...@@ -544,22 +543,23 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
if (isr & ISR_BED) { if (isr & ISR_BED) {
/* what should we do here? */ /* what should we do here? */
} else { } else {
int ret = 0; u8 byte = 0;
if (i2c->slave != NULL) if (i2c->slave != NULL)
ret = i2c->slave->read(i2c->slave->data); i2c_slave_event(i2c->slave, I2C_SLAVE_READ_PROCESSED,
&byte);
writel(ret, _IDBR(i2c)); writel(byte, _IDBR(i2c));
writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c)); /* allow next byte */ writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c)); /* allow next byte */
} }
} }
static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr) static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
{ {
unsigned int byte = readl(_IDBR(i2c)); u8 byte = readl(_IDBR(i2c));
if (i2c->slave != NULL) if (i2c->slave != NULL)
i2c->slave->write(i2c->slave->data, byte); i2c_slave_event(i2c->slave, I2C_SLAVE_WRITE_RECEIVED, &byte);
writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c)); writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
} }
...@@ -572,9 +572,18 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr) ...@@ -572,9 +572,18 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
dev_dbg(&i2c->adap.dev, "SAD, mode is slave-%cx\n", dev_dbg(&i2c->adap.dev, "SAD, mode is slave-%cx\n",
(isr & ISR_RWM) ? 'r' : 't'); (isr & ISR_RWM) ? 'r' : 't');
if (i2c->slave != NULL) if (i2c->slave != NULL) {
i2c->slave->event(i2c->slave->data, if (isr & ISR_RWM) {
(isr & ISR_RWM) ? I2C_SLAVE_EVENT_START_READ : I2C_SLAVE_EVENT_START_WRITE); u8 byte = 0;
i2c_slave_event(i2c->slave, I2C_SLAVE_READ_REQUESTED,
&byte);
writel(byte, _IDBR(i2c));
} else {
i2c_slave_event(i2c->slave, I2C_SLAVE_WRITE_REQUESTED,
NULL);
}
}
/* /*
* slave could interrupt in the middle of us generating a * slave could interrupt in the middle of us generating a
...@@ -607,7 +616,7 @@ static void i2c_pxa_slave_stop(struct pxa_i2c *i2c) ...@@ -607,7 +616,7 @@ static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop)\n"); dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop)\n");
if (i2c->slave != NULL) if (i2c->slave != NULL)
i2c->slave->event(i2c->slave->data, I2C_SLAVE_EVENT_STOP); i2c_slave_event(i2c->slave, I2C_SLAVE_STOP, NULL);
if (i2c_debug > 2) if (i2c_debug > 2)
dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop) acked\n"); dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop) acked\n");
...@@ -619,6 +628,38 @@ static void i2c_pxa_slave_stop(struct pxa_i2c *i2c) ...@@ -619,6 +628,38 @@ static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
if (i2c->msg) if (i2c->msg)
i2c_pxa_master_complete(i2c, I2C_RETRY); i2c_pxa_master_complete(i2c, I2C_RETRY);
} }
static int i2c_pxa_slave_reg(struct i2c_client *slave)
{
struct pxa_i2c *i2c = slave->adapter->algo_data;
if (i2c->slave)
return -EBUSY;
if (!i2c->reg_isar)
return -EAFNOSUPPORT;
i2c->slave = slave;
i2c->slave_addr = slave->addr;
writel(i2c->slave_addr, _ISAR(i2c));
return 0;
}
static int i2c_pxa_slave_unreg(struct i2c_client *slave)
{
struct pxa_i2c *i2c = slave->adapter->algo_data;
WARN_ON(!i2c->slave);
i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
writel(i2c->slave_addr, _ISAR(i2c));
i2c->slave = NULL;
return 0;
}
#else #else
static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr) static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
{ {
...@@ -1141,11 +1182,19 @@ static u32 i2c_pxa_functionality(struct i2c_adapter *adap) ...@@ -1141,11 +1182,19 @@ static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
static const struct i2c_algorithm i2c_pxa_algorithm = { static const struct i2c_algorithm i2c_pxa_algorithm = {
.master_xfer = i2c_pxa_xfer, .master_xfer = i2c_pxa_xfer,
.functionality = i2c_pxa_functionality, .functionality = i2c_pxa_functionality,
#ifdef CONFIG_I2C_PXA_SLAVE
.reg_slave = i2c_pxa_slave_reg,
.unreg_slave = i2c_pxa_slave_unreg,
#endif
}; };
static const struct i2c_algorithm i2c_pxa_pio_algorithm = { static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
.master_xfer = i2c_pxa_pio_xfer, .master_xfer = i2c_pxa_pio_xfer,
.functionality = i2c_pxa_functionality, .functionality = i2c_pxa_functionality,
#ifdef CONFIG_I2C_PXA_SLAVE
.reg_slave = i2c_pxa_slave_reg,
.unreg_slave = i2c_pxa_slave_unreg,
#endif
}; };
static const struct of_device_id i2c_pxa_dt_ids[] = { static const struct of_device_id i2c_pxa_dt_ids[] = {
...@@ -1270,10 +1319,6 @@ static int i2c_pxa_probe(struct platform_device *dev) ...@@ -1270,10 +1319,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c->highmode_enter = false; i2c->highmode_enter = false;
if (plat) { if (plat) {
#ifdef CONFIG_I2C_PXA_SLAVE
i2c->slave_addr = plat->slave_addr;
i2c->slave = plat->slave;
#endif
i2c->adap.class = plat->class; i2c->adap.class = plat->class;
} }
......
...@@ -628,7 +628,7 @@ static int qup_i2c_req_dma(struct qup_i2c_dev *qup) ...@@ -628,7 +628,7 @@ static int qup_i2c_req_dma(struct qup_i2c_dev *qup)
int err; int err;
if (!qup->btx.dma) { if (!qup->btx.dma) {
qup->btx.dma = dma_request_slave_channel_reason(qup->dev, "tx"); qup->btx.dma = dma_request_chan(qup->dev, "tx");
if (IS_ERR(qup->btx.dma)) { if (IS_ERR(qup->btx.dma)) {
err = PTR_ERR(qup->btx.dma); err = PTR_ERR(qup->btx.dma);
qup->btx.dma = NULL; qup->btx.dma = NULL;
...@@ -638,7 +638,7 @@ static int qup_i2c_req_dma(struct qup_i2c_dev *qup) ...@@ -638,7 +638,7 @@ static int qup_i2c_req_dma(struct qup_i2c_dev *qup)
} }
if (!qup->brx.dma) { if (!qup->brx.dma) {
qup->brx.dma = dma_request_slave_channel_reason(qup->dev, "rx"); qup->brx.dma = dma_request_chan(qup->dev, "rx");
if (IS_ERR(qup->brx.dma)) { if (IS_ERR(qup->brx.dma)) {
dev_err(qup->dev, "\n rx channel not available"); dev_err(qup->dev, "\n rx channel not available");
err = PTR_ERR(qup->brx.dma); err = PTR_ERR(qup->brx.dma);
......
...@@ -317,7 +317,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, struct i2c_timin ...@@ -317,7 +317,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, struct i2c_timin
scgd_find: scgd_find:
dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n", dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n",
scl, t->bus_freq_hz, clk_get_rate(priv->clk), round, cdf, scgd); scl, t->bus_freq_hz, rate, round, cdf, scgd);
/* keep icccr value */ /* keep icccr value */
priv->icccr = scgd << cdf_width | cdf; priv->icccr = scgd << cdf_width | cdf;
......
...@@ -486,7 +486,7 @@ static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev, ...@@ -486,7 +486,7 @@ static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev,
char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx"; char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx";
int ret; int ret;
chan = dma_request_slave_channel_reason(dev, chan_name); chan = dma_request_chan(dev, chan_name);
if (IS_ERR(chan)) { if (IS_ERR(chan)) {
dev_dbg(dev, "request_channel failed for %s (%ld)\n", chan_name, dev_dbg(dev, "request_channel failed for %s (%ld)\n", chan_name,
PTR_ERR(chan)); PTR_ERR(chan));
......
...@@ -20,13 +20,13 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev, ...@@ -20,13 +20,13 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,
dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
if (!dma) if (!dma)
return NULL; return ERR_PTR(-ENOMEM);
/* Request and configure I2C TX dma channel */ /* Request and configure I2C TX dma channel */
dma->chan_tx = dma_request_slave_channel(dev, "tx"); dma->chan_tx = dma_request_chan(dev, "tx");
if (!dma->chan_tx) { if (IS_ERR(dma->chan_tx)) {
dev_dbg(dev, "can't request DMA tx channel\n"); dev_dbg(dev, "can't request DMA tx channel\n");
ret = -EINVAL; ret = PTR_ERR(dma->chan_tx);
goto fail_al; goto fail_al;
} }
...@@ -42,10 +42,10 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev, ...@@ -42,10 +42,10 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,
} }
/* Request and configure I2C RX dma channel */ /* Request and configure I2C RX dma channel */
dma->chan_rx = dma_request_slave_channel(dev, "rx"); dma->chan_rx = dma_request_chan(dev, "rx");
if (!dma->chan_rx) { if (IS_ERR(dma->chan_rx)) {
dev_err(dev, "can't request DMA rx channel\n"); dev_err(dev, "can't request DMA rx channel\n");
ret = -EINVAL; ret = PTR_ERR(dma->chan_rx);
goto fail_tx; goto fail_tx;
} }
...@@ -75,7 +75,7 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev, ...@@ -75,7 +75,7 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,
devm_kfree(dev, dma); devm_kfree(dev, dma);
dev_info(dev, "can't use DMA\n"); dev_info(dev, "can't use DMA\n");
return NULL; return ERR_PTR(ret);
} }
void stm32_i2c_dma_free(struct stm32_i2c_dma *dma) void stm32_i2c_dma_free(struct stm32_i2c_dma *dma)
......
...@@ -1267,8 +1267,8 @@ static int stm32f7_i2c_get_free_slave_id(struct stm32f7_i2c_dev *i2c_dev, ...@@ -1267,8 +1267,8 @@ static int stm32f7_i2c_get_free_slave_id(struct stm32f7_i2c_dev *i2c_dev,
* slave[0] supports 7-bit and 10-bit slave address * slave[0] supports 7-bit and 10-bit slave address
* slave[1] supports 7-bit slave address only * slave[1] supports 7-bit slave address only
*/ */
for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) { for (i = STM32F7_I2C_MAX_SLAVE - 1; i >= 0; i--) {
if (i == 1 && (slave->flags & I2C_CLIENT_PEC)) if (i == 1 && (slave->flags & I2C_CLIENT_TEN))
continue; continue;
if (!i2c_dev->slave[i]) { if (!i2c_dev->slave[i]) {
*id = i; *id = i;
...@@ -1955,6 +1955,15 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) ...@@ -1955,6 +1955,15 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr, i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr,
STM32F7_I2C_TXDR, STM32F7_I2C_TXDR,
STM32F7_I2C_RXDR); STM32F7_I2C_RXDR);
if (PTR_ERR(i2c_dev->dma) == -ENODEV)
i2c_dev->dma = NULL;
else if (IS_ERR(i2c_dev->dma)) {
ret = PTR_ERR(i2c_dev->dma);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev,
"Failed to request dma error %i\n", ret);
goto clk_free;
}
platform_set_drvdata(pdev, i2c_dev); platform_set_drvdata(pdev, i2c_dev);
...@@ -1985,6 +1994,11 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) ...@@ -1985,6 +1994,11 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
pm_runtime_set_suspended(i2c_dev->dev); pm_runtime_set_suspended(i2c_dev->dev);
pm_runtime_dont_use_autosuspend(i2c_dev->dev); pm_runtime_dont_use_autosuspend(i2c_dev->dev);
if (i2c_dev->dma) {
stm32_i2c_dma_free(i2c_dev->dma);
i2c_dev->dma = NULL;
}
clk_free: clk_free:
clk_disable_unprepare(i2c_dev->clk); clk_disable_unprepare(i2c_dev->clk);
...@@ -1995,21 +2009,21 @@ static int stm32f7_i2c_remove(struct platform_device *pdev) ...@@ -1995,21 +2009,21 @@ static int stm32f7_i2c_remove(struct platform_device *pdev)
{ {
struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev); struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
if (i2c_dev->dma) {
stm32_i2c_dma_free(i2c_dev->dma);
i2c_dev->dma = NULL;
}
i2c_del_adapter(&i2c_dev->adap); i2c_del_adapter(&i2c_dev->adap);
pm_runtime_get_sync(i2c_dev->dev); pm_runtime_get_sync(i2c_dev->dev);
clk_disable_unprepare(i2c_dev->clk);
pm_runtime_put_noidle(i2c_dev->dev); pm_runtime_put_noidle(i2c_dev->dev);
pm_runtime_disable(i2c_dev->dev); pm_runtime_disable(i2c_dev->dev);
pm_runtime_set_suspended(i2c_dev->dev); pm_runtime_set_suspended(i2c_dev->dev);
pm_runtime_dont_use_autosuspend(i2c_dev->dev); pm_runtime_dont_use_autosuspend(i2c_dev->dev);
if (i2c_dev->dma) {
stm32_i2c_dma_free(i2c_dev->dma);
i2c_dev->dma = NULL;
}
clk_disable_unprepare(i2c_dev->clk);
return 0; return 0;
} }
......
...@@ -413,7 +413,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev) ...@@ -413,7 +413,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
return 0; return 0;
} }
chan = dma_request_slave_channel_reason(i2c_dev->dev, "rx"); chan = dma_request_chan(i2c_dev->dev, "rx");
if (IS_ERR(chan)) { if (IS_ERR(chan)) {
err = PTR_ERR(chan); err = PTR_ERR(chan);
goto err_out; goto err_out;
...@@ -421,7 +421,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev) ...@@ -421,7 +421,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
i2c_dev->rx_dma_chan = chan; i2c_dev->rx_dma_chan = chan;
chan = dma_request_slave_channel_reason(i2c_dev->dev, "tx"); chan = dma_request_chan(i2c_dev->dev, "tx");
if (IS_ERR(chan)) { if (IS_ERR(chan)) {
err = PTR_ERR(chan); err = PTR_ERR(chan);
goto err_out; goto err_out;
......
...@@ -46,6 +46,7 @@ enum xiic_endian { ...@@ -46,6 +46,7 @@ enum xiic_endian {
/** /**
* struct xiic_i2c - Internal representation of the XIIC I2C bus * struct xiic_i2c - Internal representation of the XIIC I2C bus
* @dev: Pointer to device structure
* @base: Memory base of the HW registers * @base: Memory base of the HW registers
* @wait: Wait queue for callers * @wait: Wait queue for callers
* @adap: Kernel adapter representation * @adap: Kernel adapter representation
...@@ -57,6 +58,7 @@ enum xiic_endian { ...@@ -57,6 +58,7 @@ enum xiic_endian {
* @rx_msg: Current RX message * @rx_msg: Current RX message
* @rx_pos: Position within current RX message * @rx_pos: Position within current RX message
* @endianness: big/little-endian byte order * @endianness: big/little-endian byte order
* @clk: Pointer to AXI4-lite input clock
*/ */
struct xiic_i2c { struct xiic_i2c {
struct device *dev; struct device *dev;
......
...@@ -1656,6 +1656,12 @@ void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_de ...@@ -1656,6 +1656,12 @@ void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_de
t->sda_fall_ns = t->scl_fall_ns; t->sda_fall_ns = t->scl_fall_ns;
device_property_read_u32(dev, "i2c-sda-hold-time-ns", &t->sda_hold_ns); device_property_read_u32(dev, "i2c-sda-hold-time-ns", &t->sda_hold_ns);
device_property_read_u32(dev, "i2c-digital-filter-width-ns",
&t->digital_filter_width_ns);
device_property_read_u32(dev, "i2c-analog-filter-cutoff-frequency",
&t->analog_filter_cutoff_freq_hz);
} }
EXPORT_SYMBOL_GPL(i2c_parse_fw_timings); EXPORT_SYMBOL_GPL(i2c_parse_fw_timings);
...@@ -1737,38 +1743,6 @@ EXPORT_SYMBOL(i2c_del_driver); ...@@ -1737,38 +1743,6 @@ EXPORT_SYMBOL(i2c_del_driver);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/**
* i2c_use_client - increments the reference count of the i2c client structure
* @client: the client being referenced
*
* Each live reference to a client should be refcounted. The driver model does
* that automatically as part of driver binding, so that most drivers don't
* need to do this explicitly: they hold a reference until they're unbound
* from the device.
*
* A pointer to the client with the incremented reference counter is returned.
*/
struct i2c_client *i2c_use_client(struct i2c_client *client)
{
if (client && get_device(&client->dev))
return client;
return NULL;
}
EXPORT_SYMBOL(i2c_use_client);
/**
* i2c_release_client - release a use of the i2c client structure
* @client: the client being no longer referenced
*
* Must be called when a user of a client is finished with it.
*/
void i2c_release_client(struct i2c_client *client)
{
if (client)
put_device(&client->dev);
}
EXPORT_SYMBOL(i2c_release_client);
struct i2c_cmd_arg { struct i2c_cmd_arg {
unsigned cmd; unsigned cmd;
void *arg; void *arg;
...@@ -2271,10 +2245,10 @@ int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr) ...@@ -2271,10 +2245,10 @@ int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr)
EXPORT_SYMBOL_GPL(i2c_probe_func_quick_read); EXPORT_SYMBOL_GPL(i2c_probe_func_quick_read);
struct i2c_client * struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap, i2c_new_scanned_device(struct i2c_adapter *adap,
struct i2c_board_info *info, struct i2c_board_info *info,
unsigned short const *addr_list, unsigned short const *addr_list,
int (*probe)(struct i2c_adapter *adap, unsigned short addr)) int (*probe)(struct i2c_adapter *adap, unsigned short addr))
{ {
int i; int i;
...@@ -2304,11 +2278,24 @@ i2c_new_probed_device(struct i2c_adapter *adap, ...@@ -2304,11 +2278,24 @@ i2c_new_probed_device(struct i2c_adapter *adap,
if (addr_list[i] == I2C_CLIENT_END) { if (addr_list[i] == I2C_CLIENT_END) {
dev_dbg(&adap->dev, "Probing failed, no device found\n"); dev_dbg(&adap->dev, "Probing failed, no device found\n");
return NULL; return ERR_PTR(-ENODEV);
} }
info->addr = addr_list[i]; info->addr = addr_list[i];
return i2c_new_device(adap, info); return i2c_new_client_device(adap, info);
}
EXPORT_SYMBOL_GPL(i2c_new_scanned_device);
struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap,
struct i2c_board_info *info,
unsigned short const *addr_list,
int (*probe)(struct i2c_adapter *adap, unsigned short addr))
{
struct i2c_client *client;
client = i2c_new_scanned_device(adap, info, addr_list, probe);
return IS_ERR(client) ? NULL : client;
} }
EXPORT_SYMBOL_GPL(i2c_new_probed_device); EXPORT_SYMBOL_GPL(i2c_new_probed_device);
......
...@@ -66,7 +66,6 @@ static irqreturn_t smbus_alert(int irq, void *d) ...@@ -66,7 +66,6 @@ static irqreturn_t smbus_alert(int irq, void *d)
{ {
struct i2c_smbus_alert *alert = d; struct i2c_smbus_alert *alert = d;
struct i2c_client *ara; struct i2c_client *ara;
unsigned short prev_addr = 0; /* Not a valid address */
ara = alert->ara; ara = alert->ara;
...@@ -90,18 +89,12 @@ static irqreturn_t smbus_alert(int irq, void *d) ...@@ -90,18 +89,12 @@ static irqreturn_t smbus_alert(int irq, void *d)
data.addr = status >> 1; data.addr = status >> 1;
data.type = I2C_PROTOCOL_SMBUS_ALERT; data.type = I2C_PROTOCOL_SMBUS_ALERT;
if (data.addr == prev_addr) {
dev_warn(&ara->dev, "Duplicate SMBALERT# from dev "
"0x%02x, skipping\n", data.addr);
break;
}
dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n", dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n",
data.addr, data.data); data.addr, data.data);
/* Notify driver for the device which issued the alert */ /* Notify driver for the device which issued the alert */
device_for_each_child(&ara->adapter->dev, &data, device_for_each_child(&ara->adapter->dev, &data,
smbus_do_alert); smbus_do_alert);
prev_addr = data.addr;
} }
return IRQ_HANDLED; return IRQ_HANDLED;
......
...@@ -109,14 +109,14 @@ config I2C_DEMUX_PINCTRL ...@@ -109,14 +109,14 @@ config I2C_DEMUX_PINCTRL
want to change the I2C master at run-time depending on features. want to change the I2C master at run-time depending on features.
config I2C_MUX_MLXCPLD config I2C_MUX_MLXCPLD
tristate "Mellanox CPLD based I2C multiplexer" tristate "Mellanox CPLD based I2C multiplexer"
help help
If you say yes to this option, support will be included for a If you say yes to this option, support will be included for a
CPLD based I2C multiplexer. This driver provides access to CPLD based I2C multiplexer. This driver provides access to
I2C busses connected through a MUX, which is controlled I2C busses connected through a MUX, which is controlled
by a CPLD register. by a CPLD register.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-mux-mlxcpld. will be called i2c-mux-mlxcpld.
endmenu endmenu
...@@ -716,9 +716,12 @@ static int at24_probe(struct i2c_client *client) ...@@ -716,9 +716,12 @@ static int at24_probe(struct i2c_client *client)
return -ENODEV; return -ENODEV;
} }
dev_info(dev, "%u byte %s EEPROM, %s, %u bytes/write\n", if (writable)
byte_len, client->name, dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n",
writable ? "writable" : "read-only", at24->write_max); byte_len, client->name, at24->write_max);
else
dev_info(dev, "%u byte %s EEPROM, read-only\n",
byte_len, client->name);
return 0; return 0;
} }
......
...@@ -191,8 +191,8 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) { ...@@ -191,8 +191,8 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
0x1b, I2C_CLIENT_END 0x1b, I2C_CLIENT_END
}; };
i2c_new_probed_device(&m2info->maven.adapter, i2c_new_scanned_device(&m2info->maven.adapter,
&maven_info, addr_list, NULL); &maven_info, addr_list, NULL);
} }
} }
return m2info; return m2info;
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_I2C_ALGO_PXA_H
#define _LINUX_I2C_ALGO_PXA_H
typedef enum i2c_slave_event_e {
I2C_SLAVE_EVENT_START_READ,
I2C_SLAVE_EVENT_START_WRITE,
I2C_SLAVE_EVENT_STOP
} i2c_slave_event_t;
struct i2c_slave_client {
void *data;
void (*event)(void *ptr, i2c_slave_event_t event);
int (*read) (void *ptr);
void (*write)(void *ptr, unsigned int val);
};
#endif /* _LINUX_I2C_ALGO_PXA_H */
...@@ -452,10 +452,16 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf ...@@ -452,10 +452,16 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
* a default probing method is used. * a default probing method is used.
*/ */
extern struct i2c_client * extern struct i2c_client *
i2c_new_scanned_device(struct i2c_adapter *adap,
struct i2c_board_info *info,
unsigned short const *addr_list,
int (*probe)(struct i2c_adapter *adap, unsigned short addr));
extern struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap, i2c_new_probed_device(struct i2c_adapter *adap,
struct i2c_board_info *info, struct i2c_board_info *info,
unsigned short const *addr_list, unsigned short const *addr_list,
int (*probe)(struct i2c_adapter *adap, unsigned short addr)); int (*probe)(struct i2c_adapter *adap, unsigned short addr));
/* Common custom probe functions */ /* Common custom probe functions */
extern int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr); extern int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr);
...@@ -575,6 +581,10 @@ struct i2c_lock_operations { ...@@ -575,6 +581,10 @@ struct i2c_lock_operations {
* @scl_int_delay_ns: time IP core additionally needs to setup SCL in ns * @scl_int_delay_ns: time IP core additionally needs to setup SCL in ns
* @sda_fall_ns: time SDA signal takes to fall in ns; t(f) in the I2C specification * @sda_fall_ns: time SDA signal takes to fall in ns; t(f) in the I2C specification
* @sda_hold_ns: time IP core additionally needs to hold SDA in ns * @sda_hold_ns: time IP core additionally needs to hold SDA in ns
* @digital_filter_width_ns: width in ns of spikes on i2c lines that the IP core
* digital filter can filter out
* @analog_filter_cutoff_freq_hz: threshold frequency for the low pass IP core
* analog filter
*/ */
struct i2c_timings { struct i2c_timings {
u32 bus_freq_hz; u32 bus_freq_hz;
...@@ -583,6 +593,8 @@ struct i2c_timings { ...@@ -583,6 +593,8 @@ struct i2c_timings {
u32 scl_int_delay_ns; u32 scl_int_delay_ns;
u32 sda_fall_ns; u32 sda_fall_ns;
u32 sda_hold_ns; u32 sda_hold_ns;
u32 digital_filter_width_ns;
u32 analog_filter_cutoff_freq_hz;
}; };
/** /**
...@@ -844,9 +856,6 @@ extern void i2c_del_driver(struct i2c_driver *driver); ...@@ -844,9 +856,6 @@ extern void i2c_del_driver(struct i2c_driver *driver);
#define i2c_add_driver(driver) \ #define i2c_add_driver(driver) \
i2c_register_driver(THIS_MODULE, driver) i2c_register_driver(THIS_MODULE, driver)
extern struct i2c_client *i2c_use_client(struct i2c_client *client);
extern void i2c_release_client(struct i2c_client *client);
/* call the i2c_client->command() of all attached clients with /* call the i2c_client->command() of all attached clients with
* the given arguments */ * the given arguments */
extern void i2c_clients_command(struct i2c_adapter *adap, extern void i2c_clients_command(struct i2c_adapter *adap,
......
...@@ -55,11 +55,7 @@ ...@@ -55,11 +55,7 @@
*/ */
#define I2C_ISR_INIT 0x7FF /* status register init */ #define I2C_ISR_INIT 0x7FF /* status register init */
struct i2c_slave_client;
struct i2c_pxa_platform_data { struct i2c_pxa_platform_data {
unsigned int slave_addr;
struct i2c_slave_client *slave;
unsigned int class; unsigned int class;
unsigned int use_pio :1; unsigned int use_pio :1;
unsigned int fast_mode :1; unsigned int fast_mode :1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment