diff mbox series

[RFC] i2c: i801: Add i801_register_jc42, similar to i2c_register_spd

Message ID 79977020-69c3-4f87-b861-b043c7fb9077@gmail.com
State New
Headers show
Series [RFC] i2c: i801: Add i801_register_jc42, similar to i2c_register_spd | expand

Commit Message

Heiner Kallweit Nov. 8, 2023, 7:27 a.m. UTC
As discussed, this is a RFC version of changing jc42 auto-detection
with the goal to get rid of I2C_CLASS_SPD completely mid-term.

Code of i801_jc42_probe() was copied from jc42 driver, just w/o
the device id check. I think it's safe enough w/o this check.

I don't have hw to test this, therefore it's compile-tested only.

Link: https://lore.kernel.org/linux-i2c/a22978a4-88e4-46f4-b71c-032b22321599@gmail.com/
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/i2c/busses/i2c-i801.c | 48 ++++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 4 deletions(-)

Comments

Jean Delvare Nov. 14, 2023, 2 p.m. UTC | #1
Hi Heiner,

On Wed, 08 Nov 2023 11:28:45 +0100, Heiner Kallweit wrote:
> On 08.11.2023 08:27, Heiner Kallweit wrote:
> > As discussed, this is a RFC version of changing jc42 auto-detection
> > with the goal to get rid of I2C_CLASS_SPD completely mid-term.
> > 
> > Code of i801_jc42_probe() was copied from jc42 driver, just w/o
> > the device id check. I think it's safe enough w/o this check.
> > 
> > I don't have hw to test this, therefore it's compile-tested only.
> > 
> > Link:
> > https://lore.kernel.org/linux-i2c/a22978a4-88e4-46f4-b71c-032b22321599@gmail.com/
> > Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> ---
> >  drivers/i2c/busses/i2c-i801.c | 48
> > ++++++++++++++++++++++++++++++++--- 1 file changed, 44
> > insertions(+), 4 deletions(-) 
> 
> That's quite some code for more or less nothing. I2C_CLASS_SPD is
> relevant only for users:
> - having one of the specific old ASUS machines with i2c-muxing
> - having RAM with a jc42-compatible temperature sensor
> - manually loading module jc42 to expose the temp sensor

People running such systems would typically run sensors-detect to setup
their hardware monitoring, so the jc42 driver would be loaded at boot
by the lm-sensors service. This is "manual" from the kernel's
perspective, but still this is integrated and has been working for
years. If you break that, this is a functional regression.

There is nothing fundamentally specific to i2c-i801 or these Asus
boards here. The only reason why we are discussing it in this context
is because SMBus multiplexing adds some implementation constraints, and
it turns out that right now only the i2c-i801 driver has support for
PC-style boards with multiplexed SMBus.

The solution however needs to work on all PC-style systems, Intel or
AMD (or anything else that exists), with SMBus multiplexed or not.

Originally, I2C_CLASS_SPD was there, the eeprom and jc42 drivers were
using it, and just loading these drivers would instantiate all the
devices. This is the level of user-friendliness we must aim at.

Now, the eeprom driver is gone, so class-based SPD device support no
longer exists. This was replaced by i2c_register_spd(), but is
currently only working on non-multiplexed Intel-based systems. Ideally
this should be extended to non-Intel systems (I'm surprised nobody
reported about that regression yet) and Intel systems with multiplexed
SMBus (that would be achieved by calling i2c_register_spd explicitly on
these segments, possibly with a few changes, as discussed earlier).

The jc42 driver still works the way it used to. If you remove
I2C_CLASS_SPD, this will still work on most non-SMBus-multiplexed
systems (thanks to I2C_CLASS_HWMON), but will stop working on the
multiplexed Asus boards (because the bus segments which host the memory
modules don't have I2C_CLASS_HWMON, and can't have it), or any other
board using SMbus multiplexing which we would like to support in the
future. I believe there are still many such systems out there, as
server systems with more than 8 memory slots are legions and this is
the hard limit of how many memory slots can be connected to a single
SMBus segment. We could receive a request to support such recent server
boards at any time, so we better be ready for it.

This is the reason why I asked for jc42 devices to be instantiated
automatically on multiplexed SMBus segments. The function doing that
should however not live in the i2c-i801 driver, it must be usable by
any SMBus controller driver. Also, while we only need this for
multiplexed SMBus segments, we could still use it everywhere
i2c_register_spd() is used, so that jc42 devices get instantiated at
boot-time without the need for user-space support.

> From a maintenance point of view the easiest solution would be:
> - set flag I2C_CLASS_DEPRECATED in addition to I2C_CLASS_SPD
>   to encourage potential users to switch to explicit instantiating

Bad idea. That's just going to spam a warning message on millions of
systems while there's just nothing most users can do about it. That's
not helpful, we are already aware of the problem, and we are the guys
looking into it.

> - wait few kernel versions and remove class-based instantiation

Assuming you only refer to I2C_CLASS_SPD and not I2C_CLASS_HWMON, then
yes. I2C_CLASS_HWMON must stay as there's no suitable replacement for
it yet (and sadly I can't foresee any).

I think the steps to follow are:
* Extend i2c_register_spd() to support up to 8 memory modules (I'm
  already working on that, patch is coming).
* Call i2c_register_spd() on the mux'd SMBus segments on the Asus
  boards.
* Extend i2c_register_spd() to also instantiate jc42 devices in
  addition to at24 (or ee1004) devices. I think this is better than
  writing a separate function as I initially suggested. The reason why
  I think so is because the SPD EEPROM does contain the information
  about thermal sensor presence. So the code which instantiates the at24
  or ee1004 device could also read from it to figure out whether a jc42
  device must be instantiated. This removes the need for probing.
* Get rid of I2C_CLASS_SPD.
Heiner Kallweit Nov. 14, 2023, 2:44 p.m. UTC | #2
On 14.11.2023 15:00, Jean Delvare wrote:
> Hi Heiner,
> 
> On Wed, 08 Nov 2023 11:28:45 +0100, Heiner Kallweit wrote:
>> On 08.11.2023 08:27, Heiner Kallweit wrote:
>>> As discussed, this is a RFC version of changing jc42 auto-detection
>>> with the goal to get rid of I2C_CLASS_SPD completely mid-term.
>>>
>>> Code of i801_jc42_probe() was copied from jc42 driver, just w/o
>>> the device id check. I think it's safe enough w/o this check.
>>>
>>> I don't have hw to test this, therefore it's compile-tested only.
>>>
>>> Link:
>>> https://lore.kernel.org/linux-i2c/a22978a4-88e4-46f4-b71c-032b22321599@gmail.com/
>>> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> ---
>>>  drivers/i2c/busses/i2c-i801.c | 48
>>> ++++++++++++++++++++++++++++++++--- 1 file changed, 44
>>> insertions(+), 4 deletions(-) 
>>
>> That's quite some code for more or less nothing. I2C_CLASS_SPD is
>> relevant only for users:
>> - having one of the specific old ASUS machines with i2c-muxing
>> - having RAM with a jc42-compatible temperature sensor
>> - manually loading module jc42 to expose the temp sensor
> 
> People running such systems would typically run sensors-detect to setup
> their hardware monitoring, so the jc42 driver would be loaded at boot
> by the lm-sensors service. This is "manual" from the kernel's
> perspective, but still this is integrated and has been working for
> years. If you break that, this is a functional regression.
> 
> There is nothing fundamentally specific to i2c-i801 or these Asus
> boards here. The only reason why we are discussing it in this context
> is because SMBus multiplexing adds some implementation constraints, and
> it turns out that right now only the i2c-i801 driver has support for
> PC-style boards with multiplexed SMBus.
> 
> The solution however needs to work on all PC-style systems, Intel or
> AMD (or anything else that exists), with SMBus multiplexed or not.
> 
> Originally, I2C_CLASS_SPD was there, the eeprom and jc42 drivers were
> using it, and just loading these drivers would instantiate all the
> devices. This is the level of user-friendliness we must aim at.
> 
> Now, the eeprom driver is gone, so class-based SPD device support no
> longer exists. This was replaced by i2c_register_spd(), but is
> currently only working on non-multiplexed Intel-based systems. Ideally
> this should be extended to non-Intel systems (I'm surprised nobody
> reported about that regression yet) and Intel systems with multiplexed
> SMBus (that would be achieved by calling i2c_register_spd explicitly on
> these segments, possibly with a few changes, as discussed earlier).
> 
> The jc42 driver still works the way it used to. If you remove
> I2C_CLASS_SPD, this will still work on most non-SMBus-multiplexed
> systems (thanks to I2C_CLASS_HWMON), but will stop working on the
> multiplexed Asus boards (because the bus segments which host the memory
> modules don't have I2C_CLASS_HWMON, and can't have it), or any other
> board using SMbus multiplexing which we would like to support in the
> future. I believe there are still many such systems out there, as
> server systems with more than 8 memory slots are legions and this is
> the hard limit of how many memory slots can be connected to a single
> SMBus segment. We could receive a request to support such recent server
> boards at any time, so we better be ready for it.
> 
> This is the reason why I asked for jc42 devices to be instantiated
> automatically on multiplexed SMBus segments. The function doing that
> should however not live in the i2c-i801 driver, it must be usable by
> any SMBus controller driver. Also, while we only need this for
> multiplexed SMBus segments, we could still use it everywhere
> i2c_register_spd() is used, so that jc42 devices get instantiated at
> boot-time without the need for user-space support.
> 
>> From a maintenance point of view the easiest solution would be:
>> - set flag I2C_CLASS_DEPRECATED in addition to I2C_CLASS_SPD
>>   to encourage potential users to switch to explicit instantiating
> 
> Bad idea. That's just going to spam a warning message on millions of
> systems while there's just nothing most users can do about it. That's
> not helpful, we are already aware of the problem, and we are the guys
> looking into it.
> 
I'm afraid I wasn't precise enough when writing this. What I meant is
adding I2C_CLASS_DEPRECATED for the mux'ed child segments in i801.
So it should affect users of the few Asus systems only.
i2c_register_spd() isn't used there, so I'd assume these users don't
miss the temp sensors on their RAM modules.

>> - wait few kernel versions and remove class-based instantiation
> 
> Assuming you only refer to I2C_CLASS_SPD and not I2C_CLASS_HWMON, then
> yes. I2C_CLASS_HWMON must stay as there's no suitable replacement for
> it yet (and sadly I can't foresee any).
> 
Sure, I was referring to I2C_CLASS_SPD only. A lot of hwmon drivers
support auto-detection, so getting rid of I2C_CLASS_HWMON would be
much harder.

> I think the steps to follow are:
> * Extend i2c_register_spd() to support up to 8 memory modules (I'm
>   already working on that, patch is coming).
> * Call i2c_register_spd() on the mux'd SMBus segments on the Asus
>   boards.
> * Extend i2c_register_spd() to also instantiate jc42 devices in
>   addition to at24 (or ee1004) devices. I think this is better than
>   writing a separate function as I initially suggested. The reason why
>   I think so is because the SPD EEPROM does contain the information
>   about thermal sensor presence. So the code which instantiates the at24
>   or ee1004 device could also read from it to figure out whether a jc42
>   device must be instantiated. This removes the need for probing.

I miss some insight here on which type of memory modules we can expect
jc42-4 compatible temp sensors. I saw DDR3 mentioned (including LPDDR3?),
not sure about DDR4. In case of DDR4 we would have to read the EE1004
data structure to check the "temp sensor present" bit. So I wonder
whether instantiating the temp sensor should be in ee1004 driver.

> * Get rid of I2C_CLASS_SPD.
>
Heiner Kallweit Nov. 15, 2023, 11 a.m. UTC | #3
On 14.11.2023 15:44, Heiner Kallweit wrote:
> On 14.11.2023 15:00, Jean Delvare wrote:
>> Hi Heiner,
>>
>> On Wed, 08 Nov 2023 11:28:45 +0100, Heiner Kallweit wrote:
>>> On 08.11.2023 08:27, Heiner Kallweit wrote:
>>>> As discussed, this is a RFC version of changing jc42 auto-detection
>>>> with the goal to get rid of I2C_CLASS_SPD completely mid-term.
>>>>
>>>> Code of i801_jc42_probe() was copied from jc42 driver, just w/o
>>>> the device id check. I think it's safe enough w/o this check.
>>>>
>>>> I don't have hw to test this, therefore it's compile-tested only.
>>>>
>>>> Link:
>>>> https://lore.kernel.org/linux-i2c/a22978a4-88e4-46f4-b71c-032b22321599@gmail.com/
>>>> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> ---
>>>>  drivers/i2c/busses/i2c-i801.c | 48
>>>> ++++++++++++++++++++++++++++++++--- 1 file changed, 44
>>>> insertions(+), 4 deletions(-) 
>>>
>>> That's quite some code for more or less nothing. I2C_CLASS_SPD is
>>> relevant only for users:
>>> - having one of the specific old ASUS machines with i2c-muxing
>>> - having RAM with a jc42-compatible temperature sensor
>>> - manually loading module jc42 to expose the temp sensor
>>
>> People running such systems would typically run sensors-detect to setup
>> their hardware monitoring, so the jc42 driver would be loaded at boot
>> by the lm-sensors service. This is "manual" from the kernel's
>> perspective, but still this is integrated and has been working for
>> years. If you break that, this is a functional regression.
>>
>> There is nothing fundamentally specific to i2c-i801 or these Asus
>> boards here. The only reason why we are discussing it in this context
>> is because SMBus multiplexing adds some implementation constraints, and
>> it turns out that right now only the i2c-i801 driver has support for
>> PC-style boards with multiplexed SMBus.
>>
>> The solution however needs to work on all PC-style systems, Intel or
>> AMD (or anything else that exists), with SMBus multiplexed or not.
>>
>> Originally, I2C_CLASS_SPD was there, the eeprom and jc42 drivers were
>> using it, and just loading these drivers would instantiate all the
>> devices. This is the level of user-friendliness we must aim at.
>>
>> Now, the eeprom driver is gone, so class-based SPD device support no
>> longer exists. This was replaced by i2c_register_spd(), but is
>> currently only working on non-multiplexed Intel-based systems. Ideally
>> this should be extended to non-Intel systems (I'm surprised nobody
>> reported about that regression yet) and Intel systems with multiplexed
>> SMBus (that would be achieved by calling i2c_register_spd explicitly on
>> these segments, possibly with a few changes, as discussed earlier).
>>
>> The jc42 driver still works the way it used to. If you remove
>> I2C_CLASS_SPD, this will still work on most non-SMBus-multiplexed
>> systems (thanks to I2C_CLASS_HWMON), but will stop working on the
>> multiplexed Asus boards (because the bus segments which host the memory
>> modules don't have I2C_CLASS_HWMON, and can't have it), or any other
>> board using SMbus multiplexing which we would like to support in the
>> future. I believe there are still many such systems out there, as
>> server systems with more than 8 memory slots are legions and this is
>> the hard limit of how many memory slots can be connected to a single
>> SMBus segment. We could receive a request to support such recent server
>> boards at any time, so we better be ready for it.
>>
>> This is the reason why I asked for jc42 devices to be instantiated
>> automatically on multiplexed SMBus segments. The function doing that
>> should however not live in the i2c-i801 driver, it must be usable by
>> any SMBus controller driver. Also, while we only need this for
>> multiplexed SMBus segments, we could still use it everywhere
>> i2c_register_spd() is used, so that jc42 devices get instantiated at
>> boot-time without the need for user-space support.
>>
>>> From a maintenance point of view the easiest solution would be:
>>> - set flag I2C_CLASS_DEPRECATED in addition to I2C_CLASS_SPD
>>>   to encourage potential users to switch to explicit instantiating
>>
>> Bad idea. That's just going to spam a warning message on millions of
>> systems while there's just nothing most users can do about it. That's
>> not helpful, we are already aware of the problem, and we are the guys
>> looking into it.
>>
> I'm afraid I wasn't precise enough when writing this. What I meant is
> adding I2C_CLASS_DEPRECATED for the mux'ed child segments in i801.
> So it should affect users of the few Asus systems only.
> i2c_register_spd() isn't used there, so I'd assume these users don't
> miss the temp sensors on their RAM modules.
> 
>>> - wait few kernel versions and remove class-based instantiation
>>
>> Assuming you only refer to I2C_CLASS_SPD and not I2C_CLASS_HWMON, then
>> yes. I2C_CLASS_HWMON must stay as there's no suitable replacement for
>> it yet (and sadly I can't foresee any).
>>
> Sure, I was referring to I2C_CLASS_SPD only. A lot of hwmon drivers
> support auto-detection, so getting rid of I2C_CLASS_HWMON would be
> much harder.
> 
>> I think the steps to follow are:
>> * Extend i2c_register_spd() to support up to 8 memory modules (I'm
>>   already working on that, patch is coming).
>> * Call i2c_register_spd() on the mux'd SMBus segments on the Asus
>>   boards.
>> * Extend i2c_register_spd() to also instantiate jc42 devices in
>>   addition to at24 (or ee1004) devices. I think this is better than
>>   writing a separate function as I initially suggested. The reason why
>>   I think so is because the SPD EEPROM does contain the information
>>   about thermal sensor presence. So the code which instantiates the at24
>>   or ee1004 device could also read from it to figure out whether a jc42
>>   device must be instantiated. This removes the need for probing.
> 
> I miss some insight here on which type of memory modules we can expect
> jc42-4 compatible temp sensors. I saw DDR3 mentioned (including LPDDR3?),
> not sure about DDR4. In case of DDR4 we would have to read the EE1004
> data structure to check the "temp sensor present" bit. So I wonder
> whether instantiating the temp sensor should be in ee1004 driver.
> 
After thinking once more about it I think we have to do it from the
ee1004 driver for DDR4. For DDR3 from at24. Only this way we can read
the "temp sensor present" flag from SPD. E.g. for ee1004 the SPD EEPROM
may be switched to the second page and we have to switch it to the first
page first.

I'll send a RFC patch for this. Unfortunately I have no RAM with temp
sensor to test it.

>> * Get rid of I2C_CLASS_SPD.
>>
>
Jean Delvare Nov. 15, 2023, 6:27 p.m. UTC | #4
On Tue, 14 Nov 2023 15:44:36 +0100, Heiner Kallweit wrote:
> On 14.11.2023 15:00, Jean Delvare wrote:
> > On Wed, 08 Nov 2023 11:28:45 +0100, Heiner Kallweit wrote:  
> >> From a maintenance point of view the easiest solution would be:
> >> - set flag I2C_CLASS_DEPRECATED in addition to I2C_CLASS_SPD
> >>   to encourage potential users to switch to explicit instantiating  
> > 
> > Bad idea. That's just going to spam a warning message on millions of
> > systems while there's just nothing most users can do about it. That's
> > not helpful, we are already aware of the problem, and we are the guys
> > looking into it.
>
> I'm afraid I wasn't precise enough when writing this. What I meant is
> adding I2C_CLASS_DEPRECATED for the mux'ed child segments in i801.
> So it should affect users of the few Asus systems only.

Oh right, should have been obvious actually. Nevertheless, my point
still stands, the purpose of I2C_CLASS_DEPRECATED is to draw the
attention of the developers, and in this case, the developers would be
us, so we are already aware.

> i2c_register_spd() isn't used there, so I'd assume these users don't
> miss the temp sensors on their RAM modules.

i2c_register_spd() only deals with SPD EEPROMs. The fact that it isn't
called for mux'd Asus boards only means that the users have to manually
declare the at24 devices from user-space (which is a regression from
earlier when just loading the eeprom driver would automatically create
the devices).

Users of these boards can still load the jc42 driver and the thermal
sensors on the memory modules will be supported, as long as
I2C_CLASS_SPD exists and is used by both i2c-i801 (for the mux'd
segments) and the jc42 driver.

> > (...)
> > I think the steps to follow are:
> > * Extend i2c_register_spd() to support up to 8 memory modules (I'm
> >   already working on that, patch is coming).
> > * Call i2c_register_spd() on the mux'd SMBus segments on the Asus
> >   boards.
> > * Extend i2c_register_spd() to also instantiate jc42 devices in
> >   addition to at24 (or ee1004) devices. I think this is better than
> >   writing a separate function as I initially suggested. The reason why
> >   I think so is because the SPD EEPROM does contain the information
> >   about thermal sensor presence. So the code which instantiates the at24
> >   or ee1004 device could also read from it to figure out whether a jc42
> >   device must be instantiated. This removes the need for probing.  
> 
> I miss some insight here on which type of memory modules we can expect
> jc42-4 compatible temp sensors. I saw DDR3 mentioned (including LPDDR3?),

The LP prefix is for low-power. For most practical purposes, on the
software side, you can consider these modules as equivalent to their
standard version, and treat them alike.

> not sure about DDR4. In case of DDR4 we would have to read the EE1004
> data structure to check the "temp sensor present" bit. So I wonder
> whether instantiating the temp sensor should be in ee1004 driver.

I wasn't sure so I looked up the technical literature. The Microchip
MCP98244 datasheet mentions use on a DDR4 memory module, and the NXP
SE97B and SE98A datasheet mentions use on DDR2 and DDR3 modules.
Jean Delvare Nov. 19, 2023, 8:39 a.m. UTC | #5
Hi Heiner,

On Wed, 15 Nov 2023 12:00:18 +0100, Heiner Kallweit wrote:
> After thinking once more about it I think we have to do it from the
> ee1004 driver for DDR4. For DDR3 from at24. Only this way we can read
> the "temp sensor present" flag from SPD. E.g. for ee1004 the SPD EEPROM
> may be switched to the second page and we have to switch it to the first
> page first.

We indeed need to read the EEPROM data at some point. My initial
thinking was to instantiate the at24 or ee1004 device first (from
i2c-smbus), then read the value from the EEPROM and instantiate the
jc42 device (still from i2c-smbus). This requires an internal read
function. I think we already have that in at24, because it uses the
nvmem framework, but ee1004 lacks it as far as I can see.

But anyway, if you have another approach which works, that's equally
fine with me.

> I'll send a RFC patch for this. Unfortunately I have no RAM with temp
> sensor to test it.

Neither do I :-(
Heiner Kallweit Nov. 21, 2023, 12:34 p.m. UTC | #6
On 19.11.2023 09:39, Jean Delvare wrote:
> Hi Heiner,
> 
> On Wed, 15 Nov 2023 12:00:18 +0100, Heiner Kallweit wrote:
>> After thinking once more about it I think we have to do it from the
>> ee1004 driver for DDR4. For DDR3 from at24. Only this way we can read
>> the "temp sensor present" flag from SPD. E.g. for ee1004 the SPD EEPROM
>> may be switched to the second page and we have to switch it to the first
>> page first.
> 
> We indeed need to read the EEPROM data at some point. My initial
> thinking was to instantiate the at24 or ee1004 device first (from
> i2c-smbus), then read the value from the EEPROM and instantiate the
> jc42 device (still from i2c-smbus). This requires an internal read
> function. I think we already have that in at24, because it uses the
> nvmem framework, but ee1004 lacks it as far as I can see.
> 
I sent RFC patches for both, ee1004 and at24.

> But anyway, if you have another approach which works, that's equally
> fine with me.
> 
>> I'll send a RFC patch for this. Unfortunately I have no RAM with temp
>> sensor to test it.
> 
> Neither do I :-(
> 
I organized a DDR4 module with temp sensor and the ee1004 RFC patch
properly instantiated the temp sensor.
Surprisingly I found that my old DDR4 modules also have a temp sensor,
it's just not advertised in SPD.
diff mbox series

Patch

diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 070999139..4d5103288 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -261,7 +261,6 @@  struct i801_mux_config {
 	char *gpio_chip;
 	unsigned values[3];
 	int n_values;
-	unsigned classes[3];
 	unsigned gpios[2];		/* Relative to gpio_chip->base */
 	int n_gpios;
 };
@@ -1298,7 +1297,6 @@  static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
 	.gpio_chip = "gpio_ich",
 	.values = { 0x02, 0x03 },
 	.n_values = 2,
-	.classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
 	.gpios = { 52, 53 },
 	.n_gpios = 2,
 };
@@ -1307,7 +1305,6 @@  static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
 	.gpio_chip = "gpio_ich",
 	.values = { 0x02, 0x03, 0x01 },
 	.n_values = 3,
-	.classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
 	.gpios = { 52, 53 },
 	.n_gpios = 2,
 };
@@ -1379,6 +1376,47 @@  static const struct dmi_system_id mux_dmi_table[] = {
 	{ }
 };
 
+#define JC42_REG_CAP		0x00
+#define JC42_REG_CONFIG		0x01
+#define JC42_REG_MANID		0x06
+#define JC42_REG_DEVICEID	0x07
+
+static int i801_jc42_probe(struct i2c_adapter *adap, unsigned short addr)
+{
+	struct i2c_client cl = {.adapter = adap, .addr = addr};
+	int cap, config, manid, devid;
+
+	cap = i2c_smbus_read_word_swapped(&cl, JC42_REG_CAP);
+	config = i2c_smbus_read_word_swapped(&cl, JC42_REG_CONFIG);
+	manid = i2c_smbus_read_word_swapped(&cl, JC42_REG_MANID);
+	devid = i2c_smbus_read_word_swapped(&cl, JC42_REG_DEVICEID);
+
+	if (cap < 0 || config < 0 || manid < 0 || devid < 0)
+		return 0;
+
+	if (cap & 0xff00 || config & 0xf800 || !manid)
+		return 0;
+
+	return 1;
+}
+
+static int i801_register_jc42(struct device *dev, void *data)
+{
+	struct i2c_adapter *adap;
+	struct i2c_client *client;
+	struct i2c_board_info info = {.type = "jc42"};
+	static const unsigned short addrs[] =
+		{0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, I2C_CLIENT_END};
+
+	adap = i2c_verify_adapter(dev);
+	if(!adap)
+		return 0;
+
+	client = i2c_new_scanned_device(adap, &info, addrs, i801_jc42_probe);
+
+	return PTR_ERR_OR_ZERO(client);
+}
+
 /* Setup multiplexing if needed */
 static void i801_add_mux(struct i801_priv *priv)
 {
@@ -1400,7 +1438,6 @@  static void i801_add_mux(struct i801_priv *priv)
 	gpio_data.parent = priv->adapter.nr;
 	gpio_data.values = mux_config->values;
 	gpio_data.n_values = mux_config->n_values;
-	gpio_data.classes = mux_config->classes;
 	gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
 
 	/* Register GPIO descriptor lookup table */
@@ -1430,6 +1467,9 @@  static void i801_add_mux(struct i801_priv *priv)
 		gpiod_remove_lookup_table(lookup);
 		dev_err(dev, "Failed to register i2c-mux-gpio device\n");
 	}
+
+	/* Ignore errors */
+	device_for_each_child(dev, NULL, i801_register_jc42);
 }
 
 static void i801_del_mux(struct i801_priv *priv)