All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: Touchpad stickiness on Dell Inspiron/XPS
       [not found] <CAGhUXvBw4rzCQrqttyyS=Psxmhppk79c6fDoxPbV91jE7fO_9A@mail.gmail.com>
@ 2021-08-27  6:57 ` Andrea Ippolito
  2021-09-23  8:47   ` Andrea Ippolito
  0 siblings, 1 reply; 20+ messages in thread
From: Andrea Ippolito @ 2021-08-27  6:57 UTC (permalink / raw)
  To: dmitry.torokhov, alex.hung; +Cc: linux-i2c, linux-input, platform-driver-x86

(resending as plain text)

Hello everyone,

I hope I find you well.

I am writing this to report a touchpad issue faced by me and several
other DELL users across several different distros (HW defect has been
ruled out by people unable to reproduce on Windows).

First thing that came to mind was to report this to the libinput
project, which I did here:

https://gitlab.freedesktop.org/libinput/libinput/-/issues/618

A similar report by another user followed shortly after:

https://gitlab.freedesktop.org/libinput/libinput/-/issues/636 (will be
closed as dupe eventually, so please keep #618 as reference)

Issue has been also reported by yet another user on reddit:

https://www.reddit.com/r/linuxhardware/comments/ofbzg3/dell_xps_15_9510_experience/h5ddy07/
and https://www.reddit.com/r/linuxhardware/comments/ofbzg3/dell_xps_15_9510_experience/h5zjwc8/?utm_source=reddit&utm_medium=web2x&context=3

And finally, I have reported it on the DELL user forums (no help
whatsoever from DELL):

https://www.dell.com/community/Inspiron/Tiger-Lake-DELL-Inspiron-Touchpad-Cursor-temporarily-drops/m-p/8021753#M126292

The investigation on the libinput side appears to be complete, as
maintainers didn't spot anything weird there (also, the issue is also
reproducible with the synaptics lib, suggesting that this might be
lower level).

Robert Martin suggested to raise this to you now, as per comment:

https://gitlab.freedesktop.org/libinput/libinput/-/issues/618#note_1042277

I'm kind of new to Linux mailing lists and bug reporting, so please
forgive me if I'm violating some rules or etiquette, I'd be glad to
rectify if that's the case.

I also don't know what is the best way to keep the conversation going,
e.g. if there's an issue tracker or instead mailing lists are the
preferred choice.

You should find some interesting data in the above mentioned reports
already, if not, please don't hesitate to let me know or chime in on
libinput issue #618 directly.

Thanks a lot in advance.

Kind regards,
Andrea IPPOLITO

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on Dell Inspiron/XPS
  2021-08-27  6:57 ` Touchpad stickiness on Dell Inspiron/XPS Andrea Ippolito
@ 2021-09-23  8:47   ` Andrea Ippolito
  2021-09-23  9:00     ` Hans de Goede
  0 siblings, 1 reply; 20+ messages in thread
From: Andrea Ippolito @ 2021-09-23  8:47 UTC (permalink / raw)
  To: dmitry.torokhov, Alex Hung; +Cc: linux-i2c, linux-input, platform-driver-x86

Hello,

has anyone had a chance to have a look at this report, and can help
making some progress on the investigation?

Please let me know if there are more suitable channels for this, since
most of the things I see in these mailing lists are patches and code
reviews, not really reports and discussions around ongoing issues.

Thanks a lot in advance.

Regards,
Andrea IPPOLITO

Il giorno ven 27 ago 2021 alle ore 08:57 Andrea Ippolito
<andrea.ippo@gmail.com> ha scritto:
>
> (resending as plain text)
>
> Hello everyone,
>
> I hope I find you well.
>
> I am writing this to report a touchpad issue faced by me and several
> other DELL users across several different distros (HW defect has been
> ruled out by people unable to reproduce on Windows).
>
> First thing that came to mind was to report this to the libinput
> project, which I did here:
>
> https://gitlab.freedesktop.org/libinput/libinput/-/issues/618
>
> A similar report by another user followed shortly after:
>
> https://gitlab.freedesktop.org/libinput/libinput/-/issues/636 (will be
> closed as dupe eventually, so please keep #618 as reference)
>
> Issue has been also reported by yet another user on reddit:
>
> https://www.reddit.com/r/linuxhardware/comments/ofbzg3/dell_xps_15_9510_experience/h5ddy07/
> and https://www.reddit.com/r/linuxhardware/comments/ofbzg3/dell_xps_15_9510_experience/h5zjwc8/?utm_source=reddit&utm_medium=web2x&context=3
>
> And finally, I have reported it on the DELL user forums (no help
> whatsoever from DELL):
>
> https://www.dell.com/community/Inspiron/Tiger-Lake-DELL-Inspiron-Touchpad-Cursor-temporarily-drops/m-p/8021753#M126292
>
> The investigation on the libinput side appears to be complete, as
> maintainers didn't spot anything weird there (also, the issue is also
> reproducible with the synaptics lib, suggesting that this might be
> lower level).
>
> Robert Martin suggested to raise this to you now, as per comment:
>
> https://gitlab.freedesktop.org/libinput/libinput/-/issues/618#note_1042277
>
> I'm kind of new to Linux mailing lists and bug reporting, so please
> forgive me if I'm violating some rules or etiquette, I'd be glad to
> rectify if that's the case.
>
> I also don't know what is the best way to keep the conversation going,
> e.g. if there's an issue tracker or instead mailing lists are the
> preferred choice.
>
> You should find some interesting data in the above mentioned reports
> already, if not, please don't hesitate to let me know or chime in on
> libinput issue #618 directly.
>
> Thanks a lot in advance.
>
> Kind regards,
> Andrea IPPOLITO

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on Dell Inspiron/XPS
  2021-09-23  8:47   ` Andrea Ippolito
@ 2021-09-23  9:00     ` Hans de Goede
  2021-09-23  9:06       ` Andrea Ippolito
  2022-01-06 13:14       ` Wolfram Sang
  0 siblings, 2 replies; 20+ messages in thread
From: Hans de Goede @ 2021-09-23  9:00 UTC (permalink / raw)
  To: Andrea Ippolito, dmitry.torokhov, Alex Hung
  Cc: linux-i2c, linux-input, platform-driver-x86

Hi Andrea,

On 9/23/21 10:47 AM, Andrea Ippolito wrote:
> Hello,
> 
> has anyone had a chance to have a look at this report, and can help
> making some progress on the investigation?
> 
> Please let me know if there are more suitable channels for this, since
> most of the things I see in these mailing lists are patches and code
> reviews, not really reports and discussions around ongoing issues.

Right, bugs are usually discussed in bugzila, you could consider
filing a bug here:

https://bugzilla.kernel.org/enter_bug.cgi?product=Drivers

But I must be honest here, I don't see much progress being made
on this until someone with a significant amount of kernel / hw-enablement
experience gets it hands on one of these models. Either because some
company wants to run Linux on an affected model and ends up paying
someone to look at this, or because someone with the necessary
skills happens to buy one and then gets annoyed enough by this to sink
enough time into the issue to figure things out.

This hw is still relatively new, so with some luck someone accidentally
fixes this while fixing another issue, which happens to have the
same root cause.

Short of one of these 2 happening I don't see this getting resolved
anytime soon. By all means, do file a bug for this, I just want to
set expectations about the (un)likelyness of this getting fixed
(or the bug getting much attention in general) beforehand.

Regards,

Hans



> 
> Thanks a lot in advance.
> 
> Regards,
> Andrea IPPOLITO
> 
> Il giorno ven 27 ago 2021 alle ore 08:57 Andrea Ippolito
> <andrea.ippo@gmail.com> ha scritto:
>>
>> (resending as plain text)
>>
>> Hello everyone,
>>
>> I hope I find you well.
>>
>> I am writing this to report a touchpad issue faced by me and several
>> other DELL users across several different distros (HW defect has been
>> ruled out by people unable to reproduce on Windows).
>>
>> First thing that came to mind was to report this to the libinput
>> project, which I did here:
>>
>> https://gitlab.freedesktop.org/libinput/libinput/-/issues/618
>>
>> A similar report by another user followed shortly after:
>>
>> https://gitlab.freedesktop.org/libinput/libinput/-/issues/636 (will be
>> closed as dupe eventually, so please keep #618 as reference)
>>
>> Issue has been also reported by yet another user on reddit:
>>
>> https://www.reddit.com/r/linuxhardware/comments/ofbzg3/dell_xps_15_9510_experience/h5ddy07/
>> and https://www.reddit.com/r/linuxhardware/comments/ofbzg3/dell_xps_15_9510_experience/h5zjwc8/?utm_source=reddit&utm_medium=web2x&context=3
>>
>> And finally, I have reported it on the DELL user forums (no help
>> whatsoever from DELL):
>>
>> https://www.dell.com/community/Inspiron/Tiger-Lake-DELL-Inspiron-Touchpad-Cursor-temporarily-drops/m-p/8021753#M126292
>>
>> The investigation on the libinput side appears to be complete, as
>> maintainers didn't spot anything weird there (also, the issue is also
>> reproducible with the synaptics lib, suggesting that this might be
>> lower level).
>>
>> Robert Martin suggested to raise this to you now, as per comment:
>>
>> https://gitlab.freedesktop.org/libinput/libinput/-/issues/618#note_1042277
>>
>> I'm kind of new to Linux mailing lists and bug reporting, so please
>> forgive me if I'm violating some rules or etiquette, I'd be glad to
>> rectify if that's the case.
>>
>> I also don't know what is the best way to keep the conversation going,
>> e.g. if there's an issue tracker or instead mailing lists are the
>> preferred choice.
>>
>> You should find some interesting data in the above mentioned reports
>> already, if not, please don't hesitate to let me know or chime in on
>> libinput issue #618 directly.
>>
>> Thanks a lot in advance.
>>
>> Kind regards,
>> Andrea IPPOLITO
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on Dell Inspiron/XPS
  2021-09-23  9:00     ` Hans de Goede
@ 2021-09-23  9:06       ` Andrea Ippolito
  2022-01-06 13:14       ` Wolfram Sang
  1 sibling, 0 replies; 20+ messages in thread
From: Andrea Ippolito @ 2021-09-23  9:06 UTC (permalink / raw)
  To: Hans de Goede
  Cc: dmitry.torokhov, Alex Hung, linux-i2c, linux-input, platform-driver-x86

Thanks a lot Hans for your quick reply :)

I will indeed proceed to filing a bug as you suggested and hope for the best.

Have a nice day!

Andrea IPPOLITO

Il giorno gio 23 set 2021 alle ore 11:00 Hans de Goede
<hdegoede@redhat.com> ha scritto:
>
> Hi Andrea,
>
> On 9/23/21 10:47 AM, Andrea Ippolito wrote:
> > Hello,
> >
> > has anyone had a chance to have a look at this report, and can help
> > making some progress on the investigation?
> >
> > Please let me know if there are more suitable channels for this, since
> > most of the things I see in these mailing lists are patches and code
> > reviews, not really reports and discussions around ongoing issues.
>
> Right, bugs are usually discussed in bugzila, you could consider
> filing a bug here:
>
> https://bugzilla.kernel.org/enter_bug.cgi?product=Drivers
>
> But I must be honest here, I don't see much progress being made
> on this until someone with a significant amount of kernel / hw-enablement
> experience gets it hands on one of these models. Either because some
> company wants to run Linux on an affected model and ends up paying
> someone to look at this, or because someone with the necessary
> skills happens to buy one and then gets annoyed enough by this to sink
> enough time into the issue to figure things out.
>
> This hw is still relatively new, so with some luck someone accidentally
> fixes this while fixing another issue, which happens to have the
> same root cause.
>
> Short of one of these 2 happening I don't see this getting resolved
> anytime soon. By all means, do file a bug for this, I just want to
> set expectations about the (un)likelyness of this getting fixed
> (or the bug getting much attention in general) beforehand.
>
> Regards,
>
> Hans
>
>
>
> >
> > Thanks a lot in advance.
> >
> > Regards,
> > Andrea IPPOLITO
> >
> > Il giorno ven 27 ago 2021 alle ore 08:57 Andrea Ippolito
> > <andrea.ippo@gmail.com> ha scritto:
> >>
> >> (resending as plain text)
> >>
> >> Hello everyone,
> >>
> >> I hope I find you well.
> >>
> >> I am writing this to report a touchpad issue faced by me and several
> >> other DELL users across several different distros (HW defect has been
> >> ruled out by people unable to reproduce on Windows).
> >>
> >> First thing that came to mind was to report this to the libinput
> >> project, which I did here:
> >>
> >> https://gitlab.freedesktop.org/libinput/libinput/-/issues/618
> >>
> >> A similar report by another user followed shortly after:
> >>
> >> https://gitlab.freedesktop.org/libinput/libinput/-/issues/636 (will be
> >> closed as dupe eventually, so please keep #618 as reference)
> >>
> >> Issue has been also reported by yet another user on reddit:
> >>
> >> https://www.reddit.com/r/linuxhardware/comments/ofbzg3/dell_xps_15_9510_experience/h5ddy07/
> >> and https://www.reddit.com/r/linuxhardware/comments/ofbzg3/dell_xps_15_9510_experience/h5zjwc8/?utm_source=reddit&utm_medium=web2x&context=3
> >>
> >> And finally, I have reported it on the DELL user forums (no help
> >> whatsoever from DELL):
> >>
> >> https://www.dell.com/community/Inspiron/Tiger-Lake-DELL-Inspiron-Touchpad-Cursor-temporarily-drops/m-p/8021753#M126292
> >>
> >> The investigation on the libinput side appears to be complete, as
> >> maintainers didn't spot anything weird there (also, the issue is also
> >> reproducible with the synaptics lib, suggesting that this might be
> >> lower level).
> >>
> >> Robert Martin suggested to raise this to you now, as per comment:
> >>
> >> https://gitlab.freedesktop.org/libinput/libinput/-/issues/618#note_1042277
> >>
> >> I'm kind of new to Linux mailing lists and bug reporting, so please
> >> forgive me if I'm violating some rules or etiquette, I'd be glad to
> >> rectify if that's the case.
> >>
> >> I also don't know what is the best way to keep the conversation going,
> >> e.g. if there's an issue tracker or instead mailing lists are the
> >> preferred choice.
> >>
> >> You should find some interesting data in the above mentioned reports
> >> already, if not, please don't hesitate to let me know or chime in on
> >> libinput issue #618 directly.
> >>
> >> Thanks a lot in advance.
> >>
> >> Kind regards,
> >> Andrea IPPOLITO
> >
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on Dell Inspiron/XPS
  2021-09-23  9:00     ` Hans de Goede
  2021-09-23  9:06       ` Andrea Ippolito
@ 2022-01-06 13:14       ` Wolfram Sang
  2022-01-11 10:34         ` Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS) Hans de Goede
  1 sibling, 1 reply; 20+ messages in thread
From: Wolfram Sang @ 2022-01-06 13:14 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Andrea Ippolito, dmitry.torokhov, Alex Hung, linux-i2c,
	linux-input, platform-driver-x86

[-- Attachment #1: Type: text/plain, Size: 736 bytes --]

Hi Hans,

bumping this old thread because there might be some progress and it
still affects quite some people.

> But I must be honest here, I don't see much progress being made
> on this until someone with a significant amount of kernel / hw-enablement
> experience gets it hands on one of these models. Either because some

So, I am quite optimistic that Andrea's issue is the same one which
Miroslav Bendik dived into [1]. I will surely try to help with part of
the PIIX I2C driver, but I lack the experience with the RMI4 driver. I
wonder if you could have a look and maybe share your thoughts?

Thanks and all the best,

   Wolfram

[1] https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-06 13:14       ` Wolfram Sang
@ 2022-01-11 10:34         ` Hans de Goede
  2022-01-11 11:13           ` Benjamin Tissoires
  0 siblings, 1 reply; 20+ messages in thread
From: Hans de Goede @ 2022-01-11 10:34 UTC (permalink / raw)
  To: Wolfram Sang, Andrea Ippolito, dmitry.torokhov, Alex Hung,
	linux-i2c, linux-input, platform-driver-x86, Benjamin Tissoires,
	Mario Limonciello

Hi Wolfram,

On 1/6/22 14:14, Wolfram Sang wrote:
> Hi Hans,
> 
> bumping this old thread because there might be some progress and it
> still affects quite some people.
> 
>> But I must be honest here, I don't see much progress being made
>> on this until someone with a significant amount of kernel / hw-enablement
>> experience gets it hands on one of these models. Either because some
> 
> So, I am quite optimistic that Andrea's issue is the same one which
> Miroslav Bendik dived into [1]. I will surely try to help with part of
> the PIIX I2C driver, but I lack the experience with the RMI4 driver. I
> wonder if you could have a look and maybe share your thoughts?
> 
> Thanks and all the best,
> 
>    Wolfram
> 
> [1] https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com

Benjamin Tissoires really is the export on the synaptics PS/2 -> switch to
smbus mode devices, he did all the initial hw-enablement for them.

Benjamin, see the email Wolfram linked above. It seems that on AMD
laptops we have synaptics intertouch devices connected to a plain
PIIX4 compatible I2C controller.

So we need to either add support for SMBUS host-notify to the
PIIX4 smbus driver (at least for AMD parts) or we need to support
OOB IRQ signalling in the rmi4 code, assuming there is an OOB IRQ
at all.

I've also added Mario Limonciello from AMD's client group to the Cc,

Mario, we can really use some help / insight from AMD here, both with
the problem to detect the IO addresses of the AMD PIIX4 compatible
smbus controller as well as with smbus host-notify support, see:

https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com

Regards,

Hans


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-11 10:34         ` Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS) Hans de Goede
@ 2022-01-11 11:13           ` Benjamin Tissoires
  2022-01-11 23:15             ` Limonciello, Mario
  0 siblings, 1 reply; 20+ messages in thread
From: Benjamin Tissoires @ 2022-01-11 11:13 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Wolfram Sang, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver,
	Mario Limonciello

On Tue, Jan 11, 2022 at 11:34 AM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi Wolfram,
>
> On 1/6/22 14:14, Wolfram Sang wrote:
> > Hi Hans,
> >
> > bumping this old thread because there might be some progress and it
> > still affects quite some people.
> >
> >> But I must be honest here, I don't see much progress being made
> >> on this until someone with a significant amount of kernel / hw-enablement
> >> experience gets it hands on one of these models. Either because some
> >
> > So, I am quite optimistic that Andrea's issue is the same one which
> > Miroslav Bendik dived into [1]. I will surely try to help with part of
> > the PIIX I2C driver, but I lack the experience with the RMI4 driver. I
> > wonder if you could have a look and maybe share your thoughts?
> >
> > Thanks and all the best,
> >
> >    Wolfram
> >
> > [1] https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com
>
> Benjamin Tissoires really is the export on the synaptics PS/2 -> switch to
> smbus mode devices, he did all the initial hw-enablement for them.
>
> Benjamin, see the email Wolfram linked above. It seems that on AMD
> laptops we have synaptics intertouch devices connected to a plain
> PIIX4 compatible I2C controller.

Oh, nice (looking at the thread). IIRC last time somebody tried to
communicate with those touchpads it wasn't working at all.

>
> So we need to either add support for SMBUS host-notify to the
> PIIX4 smbus driver (at least for AMD parts) or we need to support
> OOB IRQ signalling in the rmi4 code, assuming there is an OOB IRQ
> at all.

If the touchpad is using SMBus, we need to have Host Notify. Google
gave me the following datasheet for PIIX4
https://www.intel.com/Assets/PDF/datasheet/290562.pdf and it seems we
would need to enable something in the section 7.3.9.

However, without the hardware it's going to be tough for me to enable :/

For regular I2C touchpads, there is an OOB IRQ we can set up, but when
the devices are presented and enabled through PS/2 first, they are
using SMBus only AFAICT.

Cheers,
Benjamin

>
> I've also added Mario Limonciello from AMD's client group to the Cc,
>
> Mario, we can really use some help / insight from AMD here, both with
> the problem to detect the IO addresses of the AMD PIIX4 compatible
> smbus controller as well as with smbus host-notify support, see:
>
> https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com
>
> Regards,
>
> Hans
>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-11 11:13           ` Benjamin Tissoires
@ 2022-01-11 23:15             ` Limonciello, Mario
  2022-01-12  8:33               ` Wolfram Sang
                                 ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Limonciello, Mario @ 2022-01-11 23:15 UTC (permalink / raw)
  To: Benjamin Tissoires, Hans de Goede
  Cc: Wolfram Sang, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

+ Nehal from the AMD platform drivers team

On 1/11/2022 05:13, Benjamin Tissoires wrote:
> On Tue, Jan 11, 2022 at 11:34 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> Hi Wolfram,
>>
>> On 1/6/22 14:14, Wolfram Sang wrote:
>>> Hi Hans,
>>>
>>> bumping this old thread because there might be some progress and it
>>> still affects quite some people.
>>>
>>>> But I must be honest here, I don't see much progress being made
>>>> on this until someone with a significant amount of kernel / hw-enablement
>>>> experience gets it hands on one of these models. Either because some
>>>
>>> So, I am quite optimistic that Andrea's issue is the same one which
>>> Miroslav Bendik dived into [1]. I will surely try to help with part of
>>> the PIIX I2C driver, but I lack the experience with the RMI4 driver. I
>>> wonder if you could have a look and maybe share your thoughts?
>>>
>>> Thanks and all the best,
>>>
>>>     Wolfram
>>>
>>> [1] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fr%2FCAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ%40mail.gmail.com&amp;data=04%7C01%7Cmario.limonciello%40amd.com%7Cc0a66169619743575d0008d9d4f36227%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637774964813744208%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=2PEWQqq%2FqAl3WkxoaKYP5bqpeYoUqvgXwLxHtI5rEOQ%3D&amp;reserved=0
>>
>> Benjamin Tissoires really is the export on the synaptics PS/2 -> switch to
>> smbus mode devices, he did all the initial hw-enablement for them.
>>
>> Benjamin, see the email Wolfram linked above. It seems that on AMD
>> laptops we have synaptics intertouch devices connected to a plain
>> PIIX4 compatible I2C controller.
> 
> Oh, nice (looking at the thread). IIRC last time somebody tried to
> communicate with those touchpads it wasn't working at all.
> 
>>
>> So we need to either add support for SMBUS host-notify to the
>> PIIX4 smbus driver (at least for AMD parts) or we need to support
>> OOB IRQ signalling in the rmi4 code, assuming there is an OOB IRQ
>> at all.
> 
> If the touchpad is using SMBus, we need to have Host Notify. Google
> gave me the following datasheet for PIIX4
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.intel.com%2FAssets%2FPDF%2Fdatasheet%2F290562.pdf&amp;data=04%7C01%7Cmario.limonciello%40amd.com%7Cc0a66169619743575d0008d9d4f36227%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637774964813744208%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=SkwEfI9PxDidXisredOxjP11u%2FGwdq9UTwqqp4EOTZY%3D&amp;reserved=0 and it seems we
> would need to enable something in the section 7.3.9.

Nehal - can your team please look into the lack of 
I2C_FUNC_SMBUS_HOST_NOTIFY?  This causes SMBus touchpads to be unable to 
function out of PS/2 mode.

You can find many more details in the analysis that Miroslav did on 
what's missing in this thread:

https://lore.kernel.org/all/5fc2c68d-a9df-402a-58b5-fdd531f86b55@gmail.com/

> 
> However, without the hardware it's going to be tough for me to enable :/
> 
> For regular I2C touchpads, there is an OOB IRQ we can set up, but when
> the devices are presented and enabled through PS/2 first, they are
> using SMBus only AFAICT.
> 
> Cheers,
> Benjamin
> 
>>
>> I've also added Mario Limonciello from AMD's client group to the Cc,
>>
>> Mario, we can really use some help / insight from AMD here, both with
>> the problem to detect the IO addresses of the AMD PIIX4 compatible
>> smbus controller as well as with smbus host-notify support, see:
>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fr%2FCAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ%40mail.gmail.com&amp;data=04%7C01%7Cmario.limonciello%40amd.com%7Cc0a66169619743575d0008d9d4f36227%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637774964813744208%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=2PEWQqq%2FqAl3WkxoaKYP5bqpeYoUqvgXwLxHtI5rEOQ%3D&amp;reserved=0
>>
>> Regards,
>>
>> Hans
>>
> 

Hans,

This thread has splintered but it comes down to two pieces to this puzzle:

1) Systems returning SMBUS address 0xff

The address can be potentially be returned using port I/O or it can be 
done using MMIO.

There is already a thread in process to add support for MMIO, but last I 
heard it's waiting for review comments.

https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/

Besides receiving a review and modifying for review comments that patch 
has to spin at least one more time to extend AMD_PCI_SMBUS_REVISION_MMIO 
to 0x51 or later instead of 0x59 or later.

2) SMBus host notify (support for handling interrupts from slave device).

I've looped in the lead from the platform drivers team Nehal to comment
on adding this feature.

Now something else interesting - the SMBUS controller in these laptops 
often is listed in the ACPI tables on IRQ7 with a _HID of SMB0001.

That is adding an ISR for SMBUS Host Notify support may also potentially 
mean needing to revert 2bbb5fa37475d7aa5fa62f34db1623f3da2dfdfa

And maybe if we're lucky 
https://bugzilla.kernel.org/show_bug.cgi?id=201817 gets fixed too.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-11 23:15             ` Limonciello, Mario
@ 2022-01-12  8:33               ` Wolfram Sang
  2022-01-12 12:21                 ` Miroslav Bendík
  2022-01-12 12:31                 ` Hans de Goede
  2022-01-30 13:14               ` Miroslav Bendík
  2022-02-06 18:13               ` Miroslav Bendík
  2 siblings, 2 replies; 20+ messages in thread
From: Wolfram Sang @ 2022-01-12  8:33 UTC (permalink / raw)
  To: Limonciello, Mario
  Cc: Benjamin Tissoires, Hans de Goede, Andrea Ippolito,
	Dmitry Torokhov, Alex Hung, Linux I2C, open list:HID CORE LAYER,
	Platform Driver, Shah, Nehal-bakulchandra

[-- Attachment #1: Type: text/plain, Size: 904 bytes --]

Hi Mario,

thanks for joining the discussion!

> 1) Systems returning SMBUS address 0xff
> 
> The address can be potentially be returned using port I/O or it can be done
> using MMIO.
> 
> There is already a thread in process to add support for MMIO, but last I
> heard it's waiting for review comments.
> 
> https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/

This thread is under active discussion again.

> Now something else interesting - the SMBUS controller in these laptops often
> is listed in the ACPI tables on IRQ7 with a _HID of SMB0001.

IIRC tests done by Miroslav showed that interrupt 7 was used for
completing SMBus Block transfers and alike, but not for HostNotify. He
suspects this is wired via GPIO somehow.

Would be really cool if we can fix the bugzilla entry you mentioned as
well during all this!

Happy hacking,

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-12  8:33               ` Wolfram Sang
@ 2022-01-12 12:21                 ` Miroslav Bendík
  2022-01-12 22:54                   ` Limonciello, Mario
  2022-01-12 12:31                 ` Hans de Goede
  1 sibling, 1 reply; 20+ messages in thread
From: Miroslav Bendík @ 2022-01-12 12:21 UTC (permalink / raw)
  To: Wolfram Sang, Limonciello, Mario, Benjamin Tissoires,
	Hans de Goede, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

 > IIRC tests done by Miroslav showed that interrupt 7 was used for
 > completing SMBus Block transfers and alike, but not for HostNotify. He
 > suspects this is wired via GPIO somehow.

This is just speculation. It may be routed to GPIO pin, but think it's more
likely that AMD implements host notify. I have looked at windwos drivers and
there is only SMBus driver bundled with synaptics.

Lets look at https://www.intel.com/Assets/PDF/datasheet/290562.pdf 
(PIIX4 from
Intel). There is SMBSLVCNT register (page 152). Last bit (Slave Enable) 
should
enable interrupt on host notify if slave address matches content of SMBSLVC.
This register is described on page 135 (SMBUS SLAVE COMMAND). Registers are
accessible using PCI configuration registers. I have tried this code before
enabling interrupts without success:

pci_write_config_word(dev, SMBSLVC, 0x2c); // synaptics

I don't know if this PDF is relevant for AMD. Newest documentation from AMD,
which i found is:
https://www.amd.com/system/files/TechDocs/55072_AMD_Family_15h_Models_70h-7Fh_BKDG.pdf

This document describes SMBusSlaveControl on same address (0x08) and 
SlaveEnable
looks almost identical.

The interesting part is:

"address that matches the host controller slave port of 10h, a command field
that matches the SMBus slave control register, and a match of corresponding
enabled events"

Slave device should send address 10h automatically. Enabled events can 
be set
using SMBusSlaveEvent register. I have enabled all (set 0xff to 0x0a / 0x0b
registers), but i don't know how to set "command field". There is no 
register
named "command field". Intel has SMBSLVC, but i can't find corresponding
register on AMD.

Constant activity on I2C pins can be repeated host notify request from 
synaptics.

Last interesting fact:

I have recorded register value (except 0x02 and 0x07) after each SMBus
transaction. This is from last 2 transactions:

0200 0004 5801 0000 0fa9 00ff ff00 a8aa
0200 0001 5802 0000 0fa9 40ff ff00 a8aa

Every call has SMBusSlaveEvent (register 0x0a) 0x00 except of last 
command after
which device is initialized. After this call register has value 0x40. I have
written 0xff to this register to enable all events in probe function. I 
don't
know why it's 0x00 until last transaction.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-12  8:33               ` Wolfram Sang
  2022-01-12 12:21                 ` Miroslav Bendík
@ 2022-01-12 12:31                 ` Hans de Goede
  1 sibling, 0 replies; 20+ messages in thread
From: Hans de Goede @ 2022-01-12 12:31 UTC (permalink / raw)
  To: Wolfram Sang, Limonciello, Mario, Benjamin Tissoires,
	Andrea Ippolito, Dmitry Torokhov, Alex Hung, Linux I2C,
	open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

Hi,

On 1/12/22 09:33, Wolfram Sang wrote:
> Hi Mario,
> 
> thanks for joining the discussion!
> 
>> 1) Systems returning SMBUS address 0xff
>>
>> The address can be potentially be returned using port I/O or it can be done
>> using MMIO.
>>
>> There is already a thread in process to add support for MMIO, but last I
>> heard it's waiting for review comments.
>>
>> https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/
> 
> This thread is under active discussion again.
> 
>> Now something else interesting - the SMBUS controller in these laptops often
>> is listed in the ACPI tables on IRQ7 with a _HID of SMB0001.
> 
> IIRC tests done by Miroslav showed that interrupt 7 was used for
> completing SMBus Block transfers and alike, but not for HostNotify. He
> suspects this is wired via GPIO somehow.

I expect host-notify to use IRQ7 too, but that it first needs to be
enabled by poking some registers in the SMBUS controller.

Regards,

Hans


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-12 12:21                 ` Miroslav Bendík
@ 2022-01-12 22:54                   ` Limonciello, Mario
  2022-01-15  9:39                     ` Miroslav Bendík
  0 siblings, 1 reply; 20+ messages in thread
From: Limonciello, Mario @ 2022-01-12 22:54 UTC (permalink / raw)
  To: Miroslav Bendík, Wolfram Sang, Benjamin Tissoires,
	Hans de Goede, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

On 1/12/2022 06:21, Miroslav Bendík wrote:
>  > IIRC tests done by Miroslav showed that interrupt 7 was used for
>  > completing SMBus Block transfers and alike, but not for HostNotify. He
>  > suspects this is wired via GPIO somehow.
> 
> This is just speculation. It may be routed to GPIO pin, but think it's more
> likely that AMD implements host notify. I have looked at windwos drivers 
> and
> there is only SMBus driver bundled with synaptics.
> 
> Lets look at 
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.intel.com%2FAssets%2FPDF%2Fdatasheet%2F290562.pdf&amp;data=04%7C01%7Cmario.limonciello%40amd.com%7Cb813c9d7934b4bb971dc08d9d5c610a4%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637775869527091018%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&amp;sdata=GyQUs1tNgpQDcE%2FeoV1lF%2BKQgFZs3YDgYrP8Z5oCS2E%3D&amp;reserved=0 
> (PIIX4 from
> Intel). There is SMBSLVCNT register (page 152). Last bit (Slave Enable) 
> should
> enable interrupt on host notify if slave address matches content of 
> SMBSLVC.
> This register is described on page 135 (SMBUS SLAVE COMMAND). Registers are
> accessible using PCI configuration registers. I have tried this code before
> enabling interrupts without success:
> 
> pci_write_config_word(dev, SMBSLVC, 0x2c); // synaptics
> 
> I don't know if this PDF is relevant for AMD. Newest documentation from 
> AMD,
> which i found is:
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F55072_AMD_Family_15h_Models_70h-7Fh_BKDG.pdf&amp;data=04%7C01%7Cmario.limonciello%40amd.com%7Cb813c9d7934b4bb971dc08d9d5c610a4%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637775869527091018%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&amp;sdata=OYtn%2FisOR1uHzWVmre9wdIuFhD3PCaHqP2NTRrTh07A%3D&amp;reserved=0 
> 
> 
> This document describes SMBusSlaveControl on same address (0x08) and 
> SlaveEnable
> looks almost identical.
> 
> The interesting part is:
> 
> "address that matches the host controller slave port of 10h, a command 
> field
> that matches the SMBus slave control register, and a match of corresponding
> enabled events"
> 
> Slave device should send address 10h automatically. Enabled events can 
> be set
> using SMBusSlaveEvent register. I have enabled all (set 0xff to 0x0a / 0x0b
> registers), but i don't know how to set "command field". There is no 
> register
> named "command field". Intel has SMBSLVC, but i can't find corresponding
> register on AMD.

I think "SMBUSx11 I2CCommand" may be what you're looking for.

> 
> Constant activity on I2C pins can be repeated host notify request from 
> synaptics.
> 
> Last interesting fact:
> 
> I have recorded register value (except 0x02 and 0x07) after each SMBus
> transaction. This is from last 2 transactions:
> 
> 0200 0004 5801 0000 0fa9 00ff ff00 a8aa
> 0200 0001 5802 0000 0fa9 40ff ff00 a8aa
> 
> Every call has SMBusSlaveEvent (register 0x0a) 0x00 except of last 
> command after
> which device is initialized. After this call register has value 0x40. I 
> have
> written 0xff to this register to enable all events in probe function. I 
> don't
> know why it's 0x00 until last transaction.
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-12 22:54                   ` Limonciello, Mario
@ 2022-01-15  9:39                     ` Miroslav Bendík
  2022-01-15 13:46                       ` Limonciello, Mario
  0 siblings, 1 reply; 20+ messages in thread
From: Miroslav Bendík @ 2022-01-15  9:39 UTC (permalink / raw)
  To: Limonciello, Mario, Wolfram Sang, Benjamin Tissoires,
	Hans de Goede, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

 > I think "SMBUSx11 I2CCommand" may be what you're looking for.

This has no effect and i know (probably) why.

In AMD documentation is address ending with 0x20 ASF, not SMBus. Some 
registers
have same function and this is probably reason, why communication works.

This code should write 0x2c address to I2CCommand. If this is RW, then 
reading
should return 0x2c, but it returns 0x00.

outb_p(0x2c, (0x11 + piix4_smba)); // I2CCommand
printk(KERN_INFO "smbus I2CCommand %02x\n", inb_p(0x11 + piix4_smba));

If this is ASF, then 0x11 is read only. 0x0e, 0x0f should have initial value
0xa8 0xaa. Here is register dump:

0000 0002 5802 0000 0f59 00ff ff00 a8aa  0000 0081 0002 0400 0000 0000 
0000 0000

Now i am trying to change ASF registers instead of SMBus registers.

I have tried to enable interrupts and set listen address, but it don't 
work or
i can't recognize the difference between interrupts generated by 
transfers and
interrupts generated from slave.

outb_p(0x02, 0x15 + piix4_smba); // SlaveIntrListenEn
outb_p(0x2c << 1 | 0x01, 0x09 + piix4_smba); // ListenAdr | ListenAdrEn

Here is register dump for interrupts:

https://pastebin.com/eYnb30sL


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-15  9:39                     ` Miroslav Bendík
@ 2022-01-15 13:46                       ` Limonciello, Mario
  2022-01-15 18:10                         ` Miroslav Bendík
  2022-01-17  8:39                         ` Miroslav Bendík
  0 siblings, 2 replies; 20+ messages in thread
From: Limonciello, Mario @ 2022-01-15 13:46 UTC (permalink / raw)
  To: Miroslav Bendík, Wolfram Sang, Benjamin Tissoires,
	Hans de Goede, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

[AMD Official Use Only]

> Now i am trying to change ASF registers instead of SMBus registers.

> I have tried to enable interrupts and set listen address, but it don't
> work or
> i can't recognize the difference between interrupts generated by
> transfers and
> interrupts generated from slave.

Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).

> outb_p(0x02, 0x15 + piix4_smba); // SlaveIntrListenEn
> outb_p(0x2c << 1 | 0x01, 0x09 + piix4_smba); // ListenAdr | ListenAdrEn

ASFx04 SlaveAddress instead of  ASFx09 ListenAdr
?

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-15 13:46                       ` Limonciello, Mario
@ 2022-01-15 18:10                         ` Miroslav Bendík
  2022-01-17  8:39                         ` Miroslav Bendík
  1 sibling, 0 replies; 20+ messages in thread
From: Miroslav Bendík @ 2022-01-15 18:10 UTC (permalink / raw)
  To: Limonciello, Mario, Wolfram Sang, Benjamin Tissoires,
	Hans de Goede, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

> [AMD Official Use Only]
>
>> Now i am trying to change ASF registers instead of SMBus registers.
>> I have tried to enable interrupts and set listen address, but it don't
>> work or
>> i can't recognize the difference between interrupts generated by
>> transfers and
>> interrupts generated from slave.
> Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
>
>> outb_p(0x02, 0x15 + piix4_smba); // SlaveIntrListenEn
>> outb_p(0x2c << 1 | 0x01, 0x09 + piix4_smba); // ListenAdr | ListenAdrEn
> ASFx04 SlaveAddress instead of  ASFx09 ListenAdr
> ?

Without change, but this (0x08 or 0x10, both are not needed) starts 
generating interrupts

outb_p(0x08 << 1 | 0x01, 0x09 + piix4_smba);
outb_p(0x10 << 1 | 0x01, 0x09 + piix4_smba);

It generates interrupts with frequency 10 Hz - 0.01 Hz. I don't see correlation with trackpoint / touchpad.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-15 13:46                       ` Limonciello, Mario
  2022-01-15 18:10                         ` Miroslav Bendík
@ 2022-01-17  8:39                         ` Miroslav Bendík
  2022-01-17  9:08                           ` Hans de Goede
  1 sibling, 1 reply; 20+ messages in thread
From: Miroslav Bendík @ 2022-01-17  8:39 UTC (permalink / raw)
  To: Limonciello, Mario, Wolfram Sang, Benjamin Tissoires,
	Hans de Goede, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

> [AMD Official Use Only]
>
>> Now i am trying to change ASF registers instead of SMBus registers.
>> I have tried to enable interrupts and set listen address, but it don't
>> work or
>> i can't recognize the difference between interrupts generated by
>> transfers and
>> interrupts generated from slave.
> Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
>
>> outb_p(0x02, 0x15 + piix4_smba); // SlaveIntrListenEn
>> outb_p(0x2c << 1 | 0x01, 0x09 + piix4_smba); // ListenAdr | ListenAdrEn
> ASFx04 SlaveAddress instead of  ASFx09 ListenAdr
> ?
>
>
Little bit more informations:

Interrupts are generated only if ASFx09 ListenAdr is:

(0x08 << 1) | 0x01
(0x10 << 1) | 0x01

and touchpad is initialized with synaptics_intertouch=1

There is maybe small correlation between frequency and touch, but i am
not 100% sure.

There are no register changed in interrupt handler except of
ASFx13 DataBankSel. I can't determine if interrupt is generated from
transfer, or from external event.

ASF should be system for remote management. It should have access to
SMBus and data / command registers are identical, this means, that SMBus
should work (except block transfers).

If ASF just mirrors SMBus, then question is, why i can't access to
touchpad using SMBus? One strange thing is, that i2cdetect on standard
SMbus (0xb00), port 0 returns:

      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- 36 37 -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- 58 -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Address 0x58 is exactly 0x2c (synaptics) moved 1 bit left, but i2c-piix4
correctly moves address.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-17  8:39                         ` Miroslav Bendík
@ 2022-01-17  9:08                           ` Hans de Goede
  2022-01-23 17:25                             ` Miroslav Bendík
  0 siblings, 1 reply; 20+ messages in thread
From: Hans de Goede @ 2022-01-17  9:08 UTC (permalink / raw)
  To: Miroslav Bendík, Limonciello, Mario, Wolfram Sang,
	Benjamin Tissoires, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

Hi,

On 1/17/22 09:39, Miroslav Bendík wrote:
>> [AMD Official Use Only]
>>
>>> Now i am trying to change ASF registers instead of SMBus registers.
>>> I have tried to enable interrupts and set listen address, but it don't
>>> work or
>>> i can't recognize the difference between interrupts generated by
>>> transfers and
>>> interrupts generated from slave.
>> Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
>>
>>> outb_p(0x02, 0x15 + piix4_smba); // SlaveIntrListenEn
>>> outb_p(0x2c << 1 | 0x01, 0x09 + piix4_smba); // ListenAdr | ListenAdrEn
>> ASFx04 SlaveAddress instead of  ASFx09 ListenAdr
>> ?
>>
>>
> Little bit more informations:
> 
> Interrupts are generated only if ASFx09 ListenAdr is:
> 
> (0x08 << 1) | 0x01
> (0x10 << 1) | 0x01
> 
> and touchpad is initialized with synaptics_intertouch=1
> 
> There is maybe small correlation between frequency and touch, but i am
> not 100% sure.

I know very litlle about this, but I believe that when using
host-notify that after receiving the host-notify you are supposed to
do an I2C read from the SMBus Alert Response Address (ARA, 0x0c) to find
out the source of the notify (since multiple devices on the bus may
be notify capable). I guess that the controller may not do that itself
and that as long as you have not done it the touchpad may keep repeating
the notify.

But as said I know very little about this, so take this with a big
grain of salt :)  I guess you may want to read up a bit on how this
is supposed to work at the bus level. I believe that the SMBUS spec
is public.

Regards,

Hans




> 
> There are no register changed in interrupt handler except of
> ASFx13 DataBankSel. I can't determine if interrupt is generated from
> transfer, or from external event.
> 
> ASF should be system for remote management. It should have access to
> SMBus and data / command registers are identical, this means, that SMBus
> should work (except block transfers).
> 
> If ASF just mirrors SMBus, then question is, why i can't access to
> touchpad using SMBus? One strange thing is, that i2cdetect on standard
> SMbus (0xb00), port 0 returns:
> 
>      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
> 00:                         -- -- -- -- -- -- -- --
> 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 30: -- -- -- -- -- -- 36 37 -- -- -- -- -- -- -- --
> 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 50: 50 -- -- -- -- -- -- -- 58 -- -- -- -- -- -- --
> 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 70: -- -- -- -- -- -- -- --
> 
> Address 0x58 is exactly 0x2c (synaptics) moved 1 bit left, but i2c-piix4
> correctly moves address.
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-17  9:08                           ` Hans de Goede
@ 2022-01-23 17:25                             ` Miroslav Bendík
  0 siblings, 0 replies; 20+ messages in thread
From: Miroslav Bendík @ 2022-01-23 17:25 UTC (permalink / raw)
  To: Hans de Goede, Limonciello, Mario, Wolfram Sang,
	Benjamin Tissoires, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra


Dňa 17. 1. 2022 o 10:08 Hans de Goede napísal(a):
> Hi,
>
> On 1/17/22 09:39, Miroslav Bendík wrote:
>>> [AMD Official Use Only]
>>>
>>>> Now i am trying to change ASF registers instead of SMBus registers.
>>>> I have tried to enable interrupts and set listen address, but it don't
>>>> work or
>>>> i can't recognize the difference between interrupts generated by
>>>> transfers and
>>>> interrupts generated from slave.
>>> Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
>>>
>>>> outb_p(0x02, 0x15 + piix4_smba); // SlaveIntrListenEn
>>>> outb_p(0x2c << 1 | 0x01, 0x09 + piix4_smba); // ListenAdr | ListenAdrEn
>>> ASFx04 SlaveAddress instead of  ASFx09 ListenAdr
>>> ?
>>>
>>>
>> Little bit more informations:
>>
>> Interrupts are generated only if ASFx09 ListenAdr is:
>>
>> (0x08 << 1) | 0x01
>> (0x10 << 1) | 0x01
>>
>> and touchpad is initialized with synaptics_intertouch=1
>>
>> There is maybe small correlation between frequency and touch, but i am
>> not 100% sure.
> I know very litlle about this, but I believe that when using
> host-notify that after receiving the host-notify you are supposed to
> do an I2C read from the SMBus Alert Response Address (ARA, 0x0c) to find
> out the source of the notify (since multiple devices on the bus may
> be notify capable). I guess that the controller may not do that itself
> and that as long as you have not done it the touchpad may keep repeating
> the notify.
>
> But as said I know very little about this, so take this with a big
> grain of salt :)  I guess you may want to read up a bit on how this
> is supposed to work at the bus level. I believe that the SMBUS spec
> is public.
>
> Regards,
>
> Hans
>
>
>
>
>> There are no register changed in interrupt handler except of
>> ASFx13 DataBankSel. I can't determine if interrupt is generated from
>> transfer, or from external event.
>>
>> ASF should be system for remote management. It should have access to
>> SMBus and data / command registers are identical, this means, that SMBus
>> should work (except block transfers).
>>
>> If ASF just mirrors SMBus, then question is, why i can't access to
>> touchpad using SMBus? One strange thing is, that i2cdetect on standard
>> SMbus (0xb00), port 0 returns:
>>
>>       0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
>> 00:                         -- -- -- -- -- -- -- --
>> 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>> 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>> 30: -- -- -- -- -- -- 36 37 -- -- -- -- -- -- -- --
>> 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>> 50: 50 -- -- -- -- -- -- -- 58 -- -- -- -- -- -- --
>> 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>> 70: -- -- -- -- -- -- -- --
>>
>> Address 0x58 is exactly 0x2c (synaptics) moved 1 bit left, but i2c-piix4
>> correctly moves address.
>>
Hello,
i have no response from 0x0c (ARA). It returns -6 (ENXIO).

Exact call is:

i2c_smbus_xfer(piix4_aux_adapter, 0x0c, 0x00, I2C_SMBUS_READ, 0x00, 
I2C_SMBUS_BYTE, &data)

I hava played with ARP (address 0x61), but alweays without response (-6).

I have tried to read event status from ASF. Exact command is 0000 0001b
and subcommand 0001 0010b from ASF reference documentation. I have
enabled automatic PEC appending. I have tried to manually calculate PEC
too. To calculate PEC i have called i2c_smbus_pec with data {0xaa/b,
0x01, 0x03, 0x12, 0x10, 0x00} and then set PEC byte register, but every
call ends wih -6 (no response from device).

ASF sensor address should be 0x55 is (from register ASFx0F SensorAdr
- 0xaa shifted 1 bit right).

Exact code:

outb_p(0x20, SMBHSTCNT); // Automatically append PEC

data.block[0] = 0x03; // size
data.block[1] = 0x12; // subcommand
data.block[2] = 0x10; // version
data.block[3] = 0x00; // reserved
status = i2c_smbus_xfer(piix4_aux_adapter, 0x55, 0x00, I2C_SMBUS_WRITE, 
0x01, I2C_SMBUS_BLOCK_DATA, &data);

Interrupts are always generated after transactions. Following conditions
are necessary to generate interrupts spontaneously:

- SlaveIntrListenEn of ASFx15 SlaveEn bit set
- ListenAdr of ASFx09 set to 0x08 or 0x10
- ListenAdrEn of ASFx09 bit set
- psmouse loaded with synaptics_intertouch=1

Only ASFx13 DataBankSel is modified externally. Value is always 0x8?.
I have tried to check Databank?Full and if it set i am calling
i2c_handle_smbus_host_notify and cleaning bit. Sometimes it responds to
cursor move action, sometimes not. Sampling rate varies.

I don't know if this interrupt is host notify. It has some corellation,
but it may be something like bus error or event buffer full. I don't
know.

Here is video demonstration:

https://youtu.be/9pjxyiWA1a8

Before loading psmouse with synaptics_intertouch there are no
interrupts. After unloading, there are again no interrupts.

In ASF documentation is description of ASF_ALRT field of ASF!
description table, but my bios contains only ASFT record of MNVS
OperationRegion. I don't know if i should access this, or something
else.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-11 23:15             ` Limonciello, Mario
  2022-01-12  8:33               ` Wolfram Sang
@ 2022-01-30 13:14               ` Miroslav Bendík
  2022-02-06 18:13               ` Miroslav Bendík
  2 siblings, 0 replies; 20+ messages in thread
From: Miroslav Bendík @ 2022-01-30 13:14 UTC (permalink / raw)
  To: Limonciello, Mario, Benjamin Tissoires, Hans de Goede
  Cc: Wolfram Sang, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

Hello,
i have small status update.

First most important information:
On AMD is trackpoint connected to ASF bus (similar to SMBus, but with
other control registers).

This bus has interrupt. After boot always generates interrupts for each
transaction. After playing it stops generating interrupts for
transaction, i don't know exactly why. More important is, that it can
generate interrupts when receives message from slave to broadcast
address (0x08).

To enable interrupts we should set:

ListenAddr to 0x08 and ListenAddrEn to 1:

outb_p((0x08 << 1) | 0x01, 0x09 + piix4_smba);

Then SlaveIntrListenEn of SlaveEn should be set to 1:

outb_p(inb_p(0x15 + piix4_smba) | 0x02, 0x15 + piix4_smba);

Now funny part, how to read address of slave device
(0x2c for synaptics):

Important register is ASFx13 DataBankSel register. If interrupt is
generated from slave device, then DataBankxFull is set. Address can be
retrieved using block read from 0x07 (DataIndex) register. Before
reading register SetReadHostDataBank should be 0. After setting
DataBankSel i am reading HostControl (dummy read), then reading form
DataIndex value 0x08 (broadcast address) and 0x2c (device, that wanted
attention). I am using following code, but it don't work good. Sometimes
there is bad value, sometimes it's reversed, first read gives 0x2c,
second 0x10. Don't know why. I have looked on decompiled windows driver
from synaptics and it looks, that there is special handling for
different DataBankSel values. I don't know exactly why, but problems are
rare, for now i am ignoring problems.


static u8 read_asf_data_bank(unsigned short piix4_smba, u8 bank_number)
{
     outb_p(bank_number << 4, 0x13 + piix4_smba);
     inb_p(0x02 + piix4_smba); // reset DataIndex
     inb_p(0x07 + piix4_smba); // read SMBus broadcast address
     return inb_p(0x07 + piix4_smba);
}


static irqreturn_t piix4_isr(int irq, void *dev_id)
{
     //struct i2c_adapter *piix4_adapter = (struct i2c_adapter *)dev_id;
     //struct i2c_piix4_adapdata *adapdata = 
i2c_get_adapdata(piix4_adapter);
     unsigned short piix4_smba = 0xb20;

     u8 bank_sel;
     u8 address[2] = {0x00, 0x00};
     u8 *current_address;

     current_address = &address[0];

     bank_sel = inb_p(0x13 + piix4_smba); // DataBankSel

     if ((bank_sel & 0x0c) == 0x00) { // bits DataBankxFull not set
         return IRQ_HANDLED;
     }

     printk(KERN_INFO "Bank=%02x\n", bank_sel);

     if ((bank_sel & 0x01) == 0) { // Last touched bank is 0
         if (bank_sel & 0x08) {
             *current_address = read_asf_data_bank(piix4_smba, 1);
             current_address++;
         }
         if (bank_sel & 0x04) {
             *current_address = read_asf_data_bank(piix4_smba, 0);
         }
     }
     else { // Last touched bank is 1
         if (bank_sel & 0x04) {
             *current_address = read_asf_data_bank(piix4_smba, 0);
             current_address++;
         }
         if (bank_sel & 0x08) {
             *current_address = read_asf_data_bank(piix4_smba, 1);
         }
     }

     outb_p(bank_sel & 0x0c, 0x13 + piix4_smba); // Clear DataBankxFull

     printk(KERN_INFO "Address=%02x %02x\n", address[0] >> 1, address[1] 
 >> 1);

     if (address[0] != 0x00) {
         i2c_handle_smbus_host_notify(piix4_aux_adapter, address[0] >> 1);
     }
     if (address[1] != 0x00 && address[1] != address[0]) {
         i2c_handle_smbus_host_notify(piix4_aux_adapter, address[1] >> 1);
     }

     return IRQ_HANDLED;
}

Now, when i load module i see this in log:

i2c i2c-11: Error: no response!
rmi4_f12 rmi4-00.fn12: Failed to read object data. Code: -6.
Bank=8d
Address=2c 2c
input input92: rmi_2d_sensor_abs_report: obj[0]: type: 0x01 X: 323 Y: 
301 Z: 79 WX: 9 WY: 2
Bank=8d
Address=2c 2c
input input92: rmi_2d_sensor_abs_report: obj[0]: type: 0x01 X: 271 Y: 
378 Z: 73 WX: 8 WY: 4
Bank=8d
Address=2c 2c
input input92: rmi_2d_sensor_abs_report: obj[0]: type: 0x01 X: 468 Y: 
378 Z: 72 WX: 7 WY: 3
Bank=8d
Address=2c 2c
i2c i2c-11: Bus collision! SMBus may be locked until next hard reset. 
(sorry!)
rmi4_f12 rmi4-00.fn12: Failed to read object data. Code: -5.
Bank=8d
Address=2c 2c
input input92: rmi_2d_sensor_abs_report: obj[0]: type: 0x01 X: 563 Y: 
373 Z: 73 WX: 7 WY: 2
Bank=8d
Address=2c 2c
i2c i2c-11: Bus collision! SMBus may be locked until next hard reset. 
(sorry!)
rmi4_f12 rmi4-00.fn12: Failed to read object data. Code: -5.


There are too many bus collisions a no responses. This is my
implementation of piix4_access_asf

static s32 piix4_access_asf(struct i2c_adapter *adap, u16 addr,
          unsigned short flags, char read_write,
          u8 command, int size, union i2c_smbus_data *data)
{
     struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
     unsigned short piix4_smba = adapdata->smba;
     int timeout = 0;
     int retval;
     u8 temp;

     // Acquire IMC semaphore
     outb_p(0x01, 0x14 + piix4_smba);
     while ((++timeout < MAX_TIMEOUT) && (!((temp = inb_p(0x14 + 
piix4_smba)) & 0x01))) {
         usleep_range(250, 500);
     }
     if ((temp & 0x01) == 0) {
         printk(KERN_INFO "lock not acquired\n");
         return -EBUSY;
     }

     outb_p(0x80, 0x13 + piix4_smba); // Set DataBankSel to host bank

     retval = piix4_access(adap, addr, flags, read_write, command, size, 
data);

     // Release semphore
     outb_p(0x02, 0x14 + piix4_smba);

     return retval;
}

Before transaction i am requesting HostSemaphore. Semaphore is correctly
acquired. Always. I don't know how exactly i should avoid bus conflicts.

Interrupts are sometimes generated with low frequency, sometimes with
high frequency. I don't know exactly why. Frequency changes after
restart of psmouse driver. Frequency changes with touch activity too, if
starts generating with high frequency and then i don't touch anything,
then frequency goes down. After touchpad activity frequency again goes
up.

Here is video with current state:

https://youtu.be/tf850B7UTWA

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS)
  2022-01-11 23:15             ` Limonciello, Mario
  2022-01-12  8:33               ` Wolfram Sang
  2022-01-30 13:14               ` Miroslav Bendík
@ 2022-02-06 18:13               ` Miroslav Bendík
  2 siblings, 0 replies; 20+ messages in thread
From: Miroslav Bendík @ 2022-02-06 18:13 UTC (permalink / raw)
  To: Limonciello, Mario, Benjamin Tissoires, Hans de Goede
  Cc: Wolfram Sang, Andrea Ippolito, Dmitry Torokhov, Alex Hung,
	Linux I2C, open list:HID CORE LAYER, Platform Driver, Shah,
	Nehal-bakulchandra

[-- Attachment #1: Type: text/plain, Size: 5121 bytes --]

Hello,
feature host notify is now implemented. Trackpoint / touchpad is working 
pretty stable with high sample rate. But ... i can't disable interrupts.
It can generatete 10 000 interrupts/s in extreme case with loaded 
pinctrl_amd when device is idle. But it works: https://youtu.be/L4oKt500kNo

SMBus is probably implemented correctly. It looks, like RMI4 is sending 
notifications constantly, even when interrupt bits are clean.

Attached patch is full of hacks, i warn anyone who would like to use it, 
i am not responsible for any hardware damage and hard-coded values like 
interrupt number should be changed manually.

Now more details:

Windows driver is fully interrupt driven. Therefore i tried to implement 
interrupt driven transaction. This was pretty easy. First implemented 
function was quick write.

I thought that interrupt is triggered after each transaction. After 
first transaction no interrupt was triggered. Each next transaction 
triggered interrupt 7us after starting transaction. This was impossible, 
because quick write contains 10 bits (start, 7 bit address, r/w and ack) 
transferred at 100kHz (readed from PM register AsfClkSel). Minimum time 
is 100us. Interrupt was generated after cleaning of interrupt bit or 
after disabling device. IRQ 7 has probably wrong type / polarity.

Lets look at relevant section of DSDT:

Scope (_SB.PCI0)
{
     Device (SMB1)
     {
         Name (_HID, "SMB0001")  // _HID: Hardware ID
         Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
         {
             IO (Decode16,
                 0x0B20,             // Range Minimum
                 0x0B20,             // Range Maximum
                 0x20,               // Alignment
                 0x20,               // Length
                 )
             IRQ (Level, ActiveLow, Shared, )
                 {7}
         })
         Method (_STA, 0, NotSerialized)  // _STA: Status
         {
             Return (0x0F)
         }
     }
}

Interrupt 7 is level triggered and has active low state (standard value 
for PCI). Now lets look at /proc/interrupts

IR-IO-APIC    2-edge      timer
IR-IO-APIC    1-edge      i8042
IR-IO-APIC    7-edge      piix4_smbus
IR-IO-APIC    8-edge      rtc0
IR-IO-APIC    9-fasteoi   acpi
IR-IO-APIC   10-edge      AMDI0010:00
IR-IO-APIC   11-edge      AMDI0010:01
IR-IO-APIC   12-edge      i8042

This probably happens at signal level:

- r reset host interrupt status
- s start transaction
- e end transaction

11111111111111111111111111      111111111111111111
                          0      1                0
                          0      1                0
                          0      1                0
                          00000000                0000000
         |     |          |      |     |          |
        r-1   s-1        e-1    r-2   s-2        e-2

Interrupt is triggered on rising edge (r-2). I have tried to set type / 
polarity using devm_request_irq / irq_set_irq_type, but this has no 
effect. Temporary i have written hack to arch/x86/kernel/apic/io_apic.c:

if (mp_irq_entries == 7) {
     m->irqflag = MP_IRQPOL_ACTIVE_LOW | MP_IRQTRIG_LEVEL;
}

Now interrupt are triggered at right time with correct polarity.

PCI uses level triggered interrupts. Interrupt flags must be cleared. 
When there is not cleared interrupt flag, then interrupt will be 
triggered again and again. ASF has two interrupt flags: HostStatus.Intr 
and AsfStatus.SlaveIntr.

There is no problem with HostStatus.Intr. On slave event AsfStatus 
contains value 0x40 (6th bit set) instead of 0x20 (from documentation). 
Writing to 0x40 clears pending interrupt, 0x20 not. Disassembled windows 
driver writes to 0x40. AMD should fix this register in documentation.

Now i can load psmouse synaptics_intertouch=1 and device works great. 
Moving cursor causes bus collisions and device permanently sends host 
notify messages (cca 300 events / s), but it's stable.

After unloading psmouse or waiting few minutes device stops sending 
interrupts. After touching device interrupts are generated again. When i 
am not touching touchpad, interrupt status register contains zero, but 
host notifications are generated long time after last touch and with 
very high frequency. Interrupts are generated even when i don't call 
i2c_handle_smbus_host_notify. It can't be cause of infinite loop.

Now i don't know why RMI4 sends constantly notifications. I don't have 
current documentation (my documentation don't contains any new function 
like F03). Maybe there is new method to clear interrupts..

[-- Attachment #2: piix4_host_notify.patch --]
[-- Type: text/x-patch, Size: 25754 bytes --]

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index c1bb38493..7a8114bca 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -213,6 +213,9 @@ void mp_save_irq(struct mpc_intsrc *m)
 			return;
 	}
 
+	if (mp_irq_entries == 7) {
+		m->irqflag = MP_IRQPOL_ACTIVE_LOW | MP_IRQTRIG_LEVEL;
+	}
 	memcpy(&mp_irqs[mp_irq_entries], m, sizeof(*m));
 	if (++mp_irq_entries == MAX_IRQ_SOURCES)
 		panic("Max # of irq sources exceeded!!\n");
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 78d621290..dc3ca60a5 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -25,7 +25,7 @@ static const struct acpi_device_id forbidden_id_list[] = {
 	{"PNP0200",  0},	/* AT DMA Controller */
 	{"ACPI0009", 0},	/* IOxAPIC */
 	{"ACPI000A", 0},	/* IOAPIC */
-	{"SMB0001",  0},	/* ACPI SMBUS virtual device */
+	//{"SMB0001",  0},	/* ACPI SMBUS virtual device */
 	{"", 0},
 };
 
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 8c1b31ed0..6c516e4ea 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -33,7 +33,7 @@
 #include <linux/dmi.h>
 #include <linux/acpi.h>
 #include <linux/io.h>
-
+#include <linux/irq.h>
 
 /* PIIX4 SMBus address offsets */
 #define SMBHSTSTS	(0 + piix4_smba)
@@ -49,8 +49,49 @@
 #define SMBSLVEVT	(0xA + piix4_smba)
 #define SMBSLVDAT	(0xC + piix4_smba)
 
+/* ASF register offsets */
+#define ASF_PEC                   (0x08 + piix4_smba)
+#define ASF_LISTEN_ADR            (0x09 + piix4_smba)
+#define ASF_STATUS                (0x0a + piix4_smba)
+#define ASF_STATUS_MASK0          (0x0b + piix4_smba)
+#define ASF_STATUS_MASK1          (0x0c + piix4_smba)
+#define ASF_SLAVE_STATUS          (0x0d + piix4_smba)
+#define ASF_REMOTE_CTRL_ADR       (0x0e + piix4_smba)
+#define ASF_SENSOR_ADR            (0x0f + piix4_smba)
+#define ASF_DATA_READ_POINTER     (0x10 + piix4_smba)
+#define ASF_DATA_WRITE_POINTER    (0x11 + piix4_smba)
+#define ASF_SET_DATA_READ_POINTER (0x12 + piix4_smba)
+#define ASF_DATA_BANK_SEL         (0x13 + piix4_smba)
+#define ASF_SEMAPHORE             (0x14 + piix4_smba)
+#define ASF_SLAVE_EN              (0x15 + piix4_smba)
+#define ASF_DELAY_MASTER          (0x16 + piix4_smba)
+
+/* ASF ListenAdr */
+#define ASF_LISTEN_ADR_EN BIT(0)
+
+/* ASF status */
+#define ASF_SLAVE_INTR BIT(6)
+
+/* ASF Host status */
+#define ASF_HOST_INTR BIT(1)
+
+/* ASF Data bank sel */
+#define ASF_SET_READ_DATA_BANK_OFFSET 4
+#define ASF_DATA_BANK_LAST_TOUCH BIT(0)
+#define ASF_DATA_BANK_0_FULL BIT(2)
+#define ASF_DATA_BANK_1_FULL BIT(3)
+#define ASF_READ_HOST_DATA_BANK BIT(7)
+
+/* ASF semaphore */
+#define ASF_HOST_SEMAPHORE BIT(0)
+#define ASF_CLR_HOST_SEMAPHORE BIT(1)
+
+/* ASF slave */
+#define ASF_SLAVE_INTR_EN BIT(1)
+#define ASF_KILL_SLAVE BIT(4)
+
 /* count for request_region */
-#define SMBIOSIZE	9
+#define SMBIOSIZE	0x20
 
 /* PCI Address Constants */
 #define SMBBA		0x090
@@ -77,6 +118,7 @@
 
 /* SB800 constants */
 #define SB800_PIIX4_SMB_IDX		0xcd6
+#define SB800_PIIX4_SMB_MAP_SIZE	2
 
 #define KERNCZ_IMC_IDX			0x3e
 #define KERNCZ_IMC_DATA			0x3f
@@ -97,6 +139,12 @@
 #define SB800_PIIX4_PORT_IDX_MASK_KERNCZ	0x18
 #define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ	3
 
+#define SB800_PIIX4_FCH_PM_DECODEEN_MMIO_EN     BIT(1)
+#define SB800_PIIX4_FCH_PM_ADDR                 0xFED80300
+#define SB800_PIIX4_FCH_PM_SIZE                 8
+
+#define AMD_PCI_SMBUS_REVISION_MMIO             0x51
+
 /* insmod parameters */
 
 /* If force is set to anything different from 0, we forcibly enable the
@@ -114,6 +162,7 @@ MODULE_PARM_DESC(force_addr,
 		 "EXTREMELY DANGEROUS!");
 
 static int srvrworks_csb5_delay;
+static bool is_amd_kerncz = false;
 static struct pci_driver piix4_driver;
 
 static const struct dmi_system_id piix4_dmi_blacklist[] = {
@@ -155,6 +204,12 @@ static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
 };
 static const char *piix4_aux_port_name_sb800 = " port 1";
 
+struct sb800_mmio_cfg {
+	void __iomem *addr;
+	struct resource *res;
+	bool use_mmio;
+};
+
 struct i2c_piix4_adapdata {
 	unsigned short smba;
 
@@ -162,8 +217,94 @@ struct i2c_piix4_adapdata {
 	bool sb800_main;
 	bool notify_imc;
 	u8 port;		/* Port number, shifted */
+	struct sb800_mmio_cfg mmio_cfg;
+	struct completion *completion;
 };
 
+/*
+static void piix4_asf_dump_registers(struct i2c_adapter *piix4_adapter, char *label)
+{
+	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
+	unsigned short piix4_smba = adapdata->smba;
+	int i;
+	u8 d[0x17];
+
+	for (i = 0; i < 0x17; ++i) {
+		if (i == 2 || i == 7) {
+			d[i] = 0;
+		}
+		else {
+			d[i] = inb_p(i + piix4_smba);
+		}
+	}
+
+	dev_dbg(&piix4_adapter->dev, "ASF registers: %s    %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x    %02x%02x %02x%02x %02x%02x %02x%02x\n", label, d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15], d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23]);
+}
+*/
+
+static int piix4_sb800_region_setup(struct device *dev,
+				    struct sb800_mmio_cfg *mmio_cfg)
+{
+	if (mmio_cfg->use_mmio) {
+		struct resource *res;
+		void __iomem *addr;
+
+		res = request_mem_region(SB800_PIIX4_FCH_PM_ADDR,
+					 SB800_PIIX4_FCH_PM_SIZE,
+					 "sb800_piix4_smb");
+		if (!res) {
+			dev_err(dev,
+				"SMB base address memory region 0x%x already in use.\n",
+				SB800_PIIX4_FCH_PM_ADDR);
+			return -EBUSY;
+		}
+
+		addr = ioremap(SB800_PIIX4_FCH_PM_ADDR,
+			       SB800_PIIX4_FCH_PM_SIZE);
+		if (!addr) {
+			release_resource(res);
+			dev_err(dev, "SMB base address mapping failed.\n");
+			return -ENOMEM;
+		}
+
+		mmio_cfg->res = res;
+		mmio_cfg->addr = addr;
+	} else {
+		if (!request_muxed_region(SB800_PIIX4_SMB_IDX,
+					  SB800_PIIX4_SMB_MAP_SIZE,
+					  "sb800_piix4_smb")) {
+			dev_err(dev,
+				"SMB base address index region 0x%x already in use.\n",
+				SB800_PIIX4_SMB_IDX);
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static void piix4_sb800_region_release(struct device *dev,
+				       struct sb800_mmio_cfg *mmio_cfg)
+{
+	if (mmio_cfg->use_mmio) {
+		iounmap(mmio_cfg->addr);
+		mmio_cfg->addr = NULL;
+
+		release_resource(mmio_cfg->res);
+		mmio_cfg->res = NULL;
+	} else {
+		release_region(SB800_PIIX4_SMB_IDX,
+			       SB800_PIIX4_SMB_MAP_SIZE);
+	}
+}
+
+static bool piix4_sb800_use_mmio(struct pci_dev *PIIX4_dev)
+{
+	return (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD &&
+		PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS &&
+		PIIX4_dev->revision >= AMD_PCI_SMBUS_REVISION_MMIO);
+}
+
 static int piix4_setup(struct pci_dev *PIIX4_dev,
 		       const struct pci_device_id *id)
 {
@@ -263,12 +404,58 @@ static int piix4_setup(struct pci_dev *PIIX4_dev,
 	return piix4_smba;
 }
 
+static int piix4_setup_sb800_smba(struct pci_dev *PIIX4_dev,
+				  u8 smb_en,
+				  u8 aux,
+				  u8 *smb_en_status,
+				  unsigned short *piix4_smba)
+{
+	struct sb800_mmio_cfg mmio_cfg;
+	u8 smba_en_lo;
+	u8 smba_en_hi;
+	int retval;
+
+	mmio_cfg.use_mmio = piix4_sb800_use_mmio(PIIX4_dev);
+
+	retval = piix4_sb800_region_setup(&PIIX4_dev->dev, &mmio_cfg);
+	if (retval)
+		return retval;
+
+	if (mmio_cfg.use_mmio) {
+		iowrite32(ioread32(mmio_cfg.addr + 4) | SB800_PIIX4_FCH_PM_DECODEEN_MMIO_EN,
+			  mmio_cfg.addr + 4);
+
+		smba_en_lo = ioread8(mmio_cfg.addr);
+		smba_en_hi = ioread8(mmio_cfg.addr + 1);
+	} else {
+		outb_p(smb_en, SB800_PIIX4_SMB_IDX);
+		smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
+		outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX);
+		smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1);
+	}
+
+	piix4_sb800_region_release(&PIIX4_dev->dev, &mmio_cfg);
+
+	if (!smb_en) {
+		*smb_en_status = smba_en_lo & 0x10;
+		*piix4_smba = smba_en_hi << 8;
+		if (aux)
+			*piix4_smba |= 0x20;
+	} else {
+		*smb_en_status = smba_en_lo & 0x01;
+		*piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
+	}
+
+	return retval;
+}
+
 static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 			     const struct pci_device_id *id, u8 aux)
 {
 	unsigned short piix4_smba;
-	u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status, port_sel;
+	u8 smb_en, smb_en_status, port_sel;
 	u8 i2ccfg, i2ccfg_offset = 0x10;
+	int retval;
 
 	/* SB800 and later SMBus does not support forcing address */
 	if (force || force_addr) {
@@ -290,29 +477,10 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 	else
 		smb_en = (aux) ? 0x28 : 0x2c;
 
-	if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb")) {
-		dev_err(&PIIX4_dev->dev,
-			"SMB base address index region 0x%x already in use.\n",
-			SB800_PIIX4_SMB_IDX);
-		return -EBUSY;
-	}
-
-	outb_p(smb_en, SB800_PIIX4_SMB_IDX);
-	smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
-	outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX);
-	smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1);
-
-	release_region(SB800_PIIX4_SMB_IDX, 2);
-
-	if (!smb_en) {
-		smb_en_status = smba_en_lo & 0x10;
-		piix4_smba = smba_en_hi << 8;
-		if (aux)
-			piix4_smba |= 0x20;
-	} else {
-		smb_en_status = smba_en_lo & 0x01;
-		piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
-	}
+	retval = piix4_setup_sb800_smba(PIIX4_dev, smb_en,
+					aux, &smb_en_status, &piix4_smba);
+	if (retval)
+		return retval;
 
 	if (!smb_en_status) {
 		dev_err(&PIIX4_dev->dev,
@@ -338,23 +506,18 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 	}
 
 	/* Request the SMBus I2C bus config region */
-	if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
-		dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
-			"0x%x already in use!\n", piix4_smba + i2ccfg_offset);
-		release_region(piix4_smba, SMBIOSIZE);
-		return -EBUSY;
-	}
-	i2ccfg = inb_p(piix4_smba + i2ccfg_offset);
-	release_region(piix4_smba + i2ccfg_offset, 1);
+	if (!aux) {
+		i2ccfg = inb_p(piix4_smba + i2ccfg_offset);
 
-	if (i2ccfg & 1)
-		dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n");
-	else
-		dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");
+		if (i2ccfg & 1)
+			dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n");
+		else
+			dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");
 
-	dev_info(&PIIX4_dev->dev,
-		 "SMBus Host Controller at 0x%x, revision %d\n",
-		 piix4_smba, i2ccfg >> 4);
+		dev_info(&PIIX4_dev->dev,
+		 	"SMBus Host Controller at 0x%x, revision %d\n",
+		 	piix4_smba, i2ccfg >> 4);
+	}
 
 	/* Find which register is used for port selection */
 	if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD ||
@@ -434,6 +597,101 @@ static int piix4_setup_aux(struct pci_dev *PIIX4_dev,
 	return piix4_smba;
 }
 
+static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
+static struct i2c_adapter *piix4_aux_adapter;
+static int piix4_adapter_count;
+
+
+static u8 read_asf_data_bank(struct i2c_adapter *piix4_adapter, u8 bank_number)
+{
+	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
+	unsigned short piix4_smba = adapdata->smba;
+	u8 broadcast, addr, bank_sel;
+
+	outb_p(bank_number << ASF_SET_READ_DATA_BANK_OFFSET, ASF_DATA_BANK_SEL);
+	bank_sel = inb_p(ASF_DATA_BANK_SEL);
+	inb_p(SMBHSTCNT); // reset DataIndex
+	broadcast = inb_p(SMBBLKDAT);
+	addr = inb_p(SMBBLKDAT);
+
+	dev_dbg(&piix4_adapter->dev, "BankSel=%02x Data=%02x %02x\n", bank_sel, broadcast, addr);
+
+	if (broadcast != 0x10) {
+		return 0;
+	}
+
+	return addr;
+}
+
+
+static irqreturn_t piix4_isr(int irq, void *dev_id)
+{
+	struct i2c_adapter *piix4_adapter = (struct i2c_adapter *)dev_id;
+	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
+	unsigned short piix4_smba = adapdata->smba;
+
+	u8 host_status;
+	u8 bank_sel;
+	u8 asf_status;
+	u8 address[2] = {0x00, 0x00};
+	u8 *current_address;
+
+	inb_p(SMBHSTCNT);
+	host_status = inb_p(SMBHSTSTS);
+
+	// Clear HostStatus Intr and complete waiting
+	if (host_status & ASF_HOST_INTR) {
+		outb_p(ASF_HOST_INTR, SMBHSTSTS);
+
+		if (adapdata->completion) {
+			complete(adapdata->completion); // Notify caller
+		}
+	}
+
+	current_address = &address[0];
+
+	bank_sel = inb_p(ASF_DATA_BANK_SEL); // DataBankSel
+
+	if ((bank_sel & ASF_DATA_BANK_LAST_TOUCH) == 0) { // Last touched bank is 0
+		if (bank_sel & ASF_DATA_BANK_1_FULL) {
+			*current_address = read_asf_data_bank(piix4_adapter, 1);
+			current_address++;
+		}
+		if (bank_sel & ASF_DATA_BANK_0_FULL) {
+			*current_address = read_asf_data_bank(piix4_adapter, 0);
+		}
+	}
+	else { // Last touched bank is 1
+		if (bank_sel & ASF_DATA_BANK_0_FULL) {
+			*current_address = read_asf_data_bank(piix4_adapter, 0);
+			current_address++;
+		}
+		if (bank_sel & ASF_DATA_BANK_1_FULL) {
+			*current_address = read_asf_data_bank(piix4_adapter, 1);
+		}
+	}
+
+	outb_p(bank_sel & (ASF_DATA_BANK_0_FULL | ASF_DATA_BANK_1_FULL), ASF_DATA_BANK_SEL); // Clear DataBankxFull
+
+	// Trigger notifications
+	if (address[0] != 0x00) {
+		i2c_handle_smbus_host_notify(piix4_aux_adapter, address[0] >> 1);
+	}
+	if (address[1] != 0x00) {
+		i2c_handle_smbus_host_notify(piix4_aux_adapter, address[1] >> 1);
+	}
+
+	// Clean ASFStatus SlaveIntr
+	asf_status = inb_p(ASF_STATUS);
+	if (asf_status & ASF_SLAVE_INTR) {
+		outb_p(ASF_SLAVE_INTR, (ASF_STATUS)); // ASFStatus SlaveIntr? (in doc 0x20)
+	}
+
+	dev_dbg(&piix4_adapter->dev,"Interrupt HostStatus=%02x BankSel=%02x AsfStatus=%02x\n", host_status, bank_sel, asf_status);
+
+	return IRQ_HANDLED;
+}
+
 static int piix4_transaction(struct i2c_adapter *piix4_adapter)
 {
 	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
@@ -463,20 +721,30 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter)
 	/* start the transaction by setting bit 6 */
 	outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
 
-	/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
-	if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
-		usleep_range(2000, 2100);
-	else
-		usleep_range(250, 500);
-
-	while ((++timeout < MAX_TIMEOUT) &&
-	       ((temp = inb_p(SMBHSTSTS)) & 0x01))
-		usleep_range(250, 500);
-
-	/* If the SMBus is still busy, we give up */
-	if (timeout == MAX_TIMEOUT) {
-		dev_err(&piix4_adapter->dev, "SMBus Timeout!\n");
-		result = -ETIMEDOUT;
+	if (adapdata->completion) {
+		timeout = wait_for_completion_timeout(adapdata->completion, msecs_to_jiffies(100));
+		if (timeout == 0) {
+			dev_err(&piix4_adapter->dev, "SMBus Timeout!\n");
+			result = -ETIMEDOUT;
+		}
+		temp = inb_p(SMBHSTSTS);
+	}
+	else {
+		/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
+		if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
+			usleep_range(2000, 2100);
+		else
+			usleep_range(250, 500);
+
+		while ((++timeout < MAX_TIMEOUT) &&
+		       ((temp = inb_p(SMBHSTSTS)) & 0x01))
+			usleep_range(250, 500);
+
+		/* If the SMBus is still busy, we give up */
+		if (timeout == MAX_TIMEOUT) {
+			dev_err(&piix4_adapter->dev, "SMBus Timeout!\n");
+			result = -ETIMEDOUT;
+		}
 	}
 
 	if (temp & 0x10) {
@@ -560,6 +828,9 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
 			if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
 				return -EINVAL;
 			outb_p(len, SMBHSTDAT0);
+			if (is_amd_kerncz && adap == piix4_aux_adapter) {
+				outb_p(ASF_READ_HOST_DATA_BANK, ASF_DATA_BANK_SEL); // Set DataBankSel to host bank
+			}
 			inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
 			for (i = 1; i <= len; i++)
 				outb_p(data->block[i], SMBBLKDAT);
@@ -591,8 +862,12 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
 		break;
 	case PIIX4_BLOCK_DATA:
 		data->block[0] = inb_p(SMBHSTDAT0);
-		if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
+		if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX) {
 			return -EPROTO;
+		}
+		if (is_amd_kerncz && adap == piix4_aux_adapter) {
+			outb_p(ASF_READ_HOST_DATA_BANK, ASF_DATA_BANK_SEL);
+		}
 		inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
 		for (i = 1; i <= data->block[0]; i++)
 			data->block[i] = inb_p(SMBBLKDAT);
@@ -662,6 +937,29 @@ static void piix4_imc_wakeup(void)
 	release_region(KERNCZ_IMC_IDX, 2);
 }
 
+static int piix4_sb800_port_sel(u8 port, struct sb800_mmio_cfg *mmio_cfg)
+{
+	u8 smba_en_lo;
+
+	if (mmio_cfg->use_mmio) {
+		smba_en_lo = ioread8(mmio_cfg->addr + piix4_port_sel_sb800);
+
+		if ((smba_en_lo & piix4_port_mask_sb800) != port)
+			iowrite8((smba_en_lo & ~piix4_port_mask_sb800) | port,
+				 mmio_cfg->addr + piix4_port_sel_sb800);
+	} else {
+		outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
+		smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
+
+		if ((smba_en_lo & piix4_port_mask_sb800) != port)
+			outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port,
+			       SB800_PIIX4_SMB_IDX + 1);
+	}
+
+	return (smba_en_lo & piix4_port_mask_sb800);
+}
+
+
 /*
  * Handles access to multiple SMBus ports on the SB800.
  * The port is selected by bits 2:1 of the smb_en register (0x2c).
@@ -678,12 +976,12 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
 	unsigned short piix4_smba = adapdata->smba;
 	int retries = MAX_TIMEOUT;
 	int smbslvcnt;
-	u8 smba_en_lo;
-	u8 port;
+	u8 prev_port;
 	int retval;
 
-	if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb"))
-		return -EBUSY;
+	retval = piix4_sb800_region_setup(&adap->dev, &adapdata->mmio_cfg);
+	if (retval)
+		return retval;
 
 	/* Request the SMBUS semaphore, avoid conflicts with the IMC */
 	smbslvcnt  = inb_p(SMBSLVCNT);
@@ -738,18 +1036,12 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
 		}
 	}
 
-	outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
-	smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
-
-	port = adapdata->port;
-	if ((smba_en_lo & piix4_port_mask_sb800) != port)
-		outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port,
-		       SB800_PIIX4_SMB_IDX + 1);
+	prev_port = piix4_sb800_port_sel(adapdata->port, &adapdata->mmio_cfg);
 
 	retval = piix4_access(adap, addr, flags, read_write,
 			      command, size, data);
 
-	outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1);
+	piix4_sb800_port_sel(prev_port, &adapdata->mmio_cfg);
 
 	/* Release the semaphore */
 	outb_p(smbslvcnt | 0x20, SMBSLVCNT);
@@ -758,7 +1050,43 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
 		piix4_imc_wakeup();
 
 release:
-	release_region(SB800_PIIX4_SMB_IDX, 2);
+	piix4_sb800_region_release(&adap->dev, &adapdata->mmio_cfg);
+	return retval;
+}
+
+static s32 piix4_access_asf(struct i2c_adapter *adap, u16 addr,
+		 unsigned short flags, char read_write,
+		 u8 command, int size, union i2c_smbus_data *data)
+{
+	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
+	unsigned short piix4_smba = adapdata->smba;
+	int timeout = 0;
+	int retval = 0;
+	u8 temp;
+
+	if (adapdata->completion) {
+		reinit_completion(adapdata->completion);
+	}
+
+	// Acquire IMC semaphore
+	outb_p(ASF_HOST_SEMAPHORE, ASF_SEMAPHORE);
+	while ((++timeout < MAX_TIMEOUT) && (!((temp = inb_p(ASF_SEMAPHORE)) & ASF_HOST_SEMAPHORE))) {
+		usleep_range(250, 500);
+	}
+	if ((temp & ASF_HOST_SEMAPHORE) == 0) {
+		dev_dbg(&adap->dev, "Host semaphore not acquired\n");
+		return -EBUSY;
+	}
+
+	outb_p(inb_p(ASF_SLAVE_EN) | ASF_KILL_SLAVE, ASF_SLAVE_EN); // Kill slave
+
+	retval = piix4_access(adap, addr, flags, read_write, command, size, data);
+
+	outb_p(inb_p(ASF_SLAVE_EN) & (~ASF_KILL_SLAVE), ASF_SLAVE_EN); // Enable slave
+
+	// Release semphore
+	outb_p(ASF_CLR_HOST_SEMAPHORE, ASF_SEMAPHORE);
+
 	return retval;
 }
 
@@ -766,7 +1094,7 @@ static u32 piix4_func(struct i2c_adapter *adapter)
 {
 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-	    I2C_FUNC_SMBUS_BLOCK_DATA;
+	    I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_HOST_NOTIFY;
 }
 
 static const struct i2c_algorithm smbus_algorithm = {
@@ -779,6 +1107,11 @@ static const struct i2c_algorithm piix4_smbus_algorithm_sb800 = {
 	.functionality	= piix4_func,
 };
 
+static const struct i2c_algorithm piix4_smbus_algorithm_asf = {
+	.smbus_xfer	= piix4_access_asf,
+	.functionality	= piix4_func,
+};
+
 static const struct pci_device_id piix4_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
@@ -805,12 +1138,8 @@ static const struct pci_device_id piix4_ids[] = {
 
 MODULE_DEVICE_TABLE (pci, piix4_ids);
 
-static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
-static struct i2c_adapter *piix4_aux_adapter;
-static int piix4_adapter_count;
-
-static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
-			     bool sb800_main, u8 port, bool notify_imc,
+static int piix4_add_adapter(struct pci_dev *dev, unsigned short piix4_smba,
+			     bool sb800_main, int irq, u8 port, bool notify_imc,
 			     u8 hw_port_nr, const char *name,
 			     struct i2c_adapter **padap)
 {
@@ -820,26 +1149,28 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
 
 	adap = kzalloc(sizeof(*adap), GFP_KERNEL);
 	if (adap == NULL) {
-		release_region(smba, SMBIOSIZE);
+		release_region(piix4_smba, SMBIOSIZE);
 		return -ENOMEM;
 	}
 
 	adap->owner = THIS_MODULE;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->algo = sb800_main ? &piix4_smbus_algorithm_sb800
-				: &smbus_algorithm;
+				: &piix4_smbus_algorithm_asf;
 
 	adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL);
 	if (adapdata == NULL) {
 		kfree(adap);
-		release_region(smba, SMBIOSIZE);
+		release_region(piix4_smba, SMBIOSIZE);
 		return -ENOMEM;
 	}
 
-	adapdata->smba = smba;
+	adapdata->smba = piix4_smba;
 	adapdata->sb800_main = sb800_main;
 	adapdata->port = port << piix4_port_shift_sb800;
 	adapdata->notify_imc = notify_imc;
+	adapdata->mmio_cfg.use_mmio = piix4_sb800_use_mmio(dev);
+	adapdata->completion = NULL;
 
 	/* set up the sysfs linkage to our parent device */
 	adap->dev.parent = &dev->dev;
@@ -851,7 +1182,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
 	}
 
 	snprintf(adap->name, sizeof(adap->name),
-		"SMBus PIIX4 adapter%s at %04x", name, smba);
+		"SMBus PIIX4 adapter%s at %04x", name, piix4_smba);
 
 	i2c_set_adapdata(adap, adapdata);
 
@@ -859,11 +1190,29 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
 	if (retval) {
 		kfree(adapdata);
 		kfree(adap);
-		release_region(smba, SMBIOSIZE);
+		release_region(piix4_smba, SMBIOSIZE);
 		return retval;
 	}
 
 	*padap = adap;
+
+	if (irq >= 0) {
+		if (!devm_request_irq(&dev->dev, dev->irq, piix4_isr, IRQF_SHARED, "piix4_smbus", *padap)) {
+			adapdata->completion = kzalloc(sizeof(*adapdata->completion), GFP_KERNEL);
+			if (adapdata->completion == NULL) {
+				kfree(adapdata);
+				kfree(adap);
+				release_region(piix4_smba, SMBIOSIZE);
+				return -ENOMEM;
+			}
+			init_completion(adapdata->completion);
+			dev_info(&dev->dev, "SMBus using irq %d\n", dev->irq);
+			outb_p(inb_p(ASF_SLAVE_EN) | ASF_KILL_SLAVE, ASF_SLAVE_EN); // Kill slave
+			outb_p(inb_p(ASF_SLAVE_EN) & (~ASF_KILL_SLAVE), ASF_SLAVE_EN); // Enable slave
+			outb_p((0x08 << 1) | ASF_LISTEN_ADR_EN, ASF_LISTEN_ADR); // Listen SMBus broadcast
+		}
+	}
+
 	return 0;
 }
 
@@ -885,7 +1234,7 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba,
 	for (port = 0; port < piix4_adapter_count; port++) {
 		u8 hw_port_nr = port == 0 ? 0 : port + 1;
 
-		retval = piix4_add_adapter(dev, smba, true, port, notify_imc,
+		retval = piix4_add_adapter(dev, smba, true, -1, port, notify_imc,
 					   hw_port_nr,
 					   piix4_main_port_names_sb800[port],
 					   &piix4_main_adapters[port]);
@@ -957,7 +1306,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
 			return retval;
 
 		/* Try to register main SMBus adapter, give up if we can't */
-		retval = piix4_add_adapter(dev, retval, false, 0, false, 0,
+		retval = piix4_add_adapter(dev, retval, false, 0, false, -1, 0,
 					   "", &piix4_main_adapters[0]);
 		if (retval < 0)
 			return retval;
@@ -980,12 +1329,13 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	    (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS ||
 	     dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) {
 		retval = piix4_setup_sb800(dev, id, 1);
+		is_amd_kerncz = true;
 	}
 
 	if (retval > 0) {
-		/* Try to add the aux adapter if it exists,
+		/* try to add the aux adapter if it exists,
 		 * piix4_add_adapter will clean up if this fails */
-		piix4_add_adapter(dev, retval, false, 0, false, 1,
+		piix4_add_adapter(dev, retval, false, 0, false, dev->irq, 1,
 				  is_sb800 ? piix4_aux_port_name_sb800 : "",
 				  &piix4_aux_adapter);
 	}
@@ -1001,6 +1351,9 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
 		i2c_del_adapter(adap);
 		if (adapdata->port == (0 << piix4_port_shift_sb800))
 			release_region(adapdata->smba, SMBIOSIZE);
+		if (adapdata->completion) {
+			kfree(adapdata->completion);
+		}
 		kfree(adapdata);
 		kfree(adap);
 	}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 4537d1ea1..22d2375b7 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -743,6 +743,16 @@ static void quirk_piix4_acpi(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371AB_3,	quirk_piix4_acpi);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82443MX_3,	quirk_piix4_acpi);
 
+
+
+static void quirk_piix4_amd(struct pci_dev *dev) {
+	printk(KERN_INFO "piix4 fixing interrupt line");
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 7);
+	dev->irq = 7;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_KERNCZ_SMBUS,	quirk_piix4_amd);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_KERNCZ_SMBUS,	quirk_piix4_amd);
+
 #define ICH_PMBASE	0x40
 #define ICH_ACPI_CNTL	0x44
 #define  ICH4_ACPI_EN	0x10

^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2022-02-06 18:13 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAGhUXvBw4rzCQrqttyyS=Psxmhppk79c6fDoxPbV91jE7fO_9A@mail.gmail.com>
2021-08-27  6:57 ` Touchpad stickiness on Dell Inspiron/XPS Andrea Ippolito
2021-09-23  8:47   ` Andrea Ippolito
2021-09-23  9:00     ` Hans de Goede
2021-09-23  9:06       ` Andrea Ippolito
2022-01-06 13:14       ` Wolfram Sang
2022-01-11 10:34         ` Touchpad stickiness on AMD laptops (was Dell Inspiron/XPS) Hans de Goede
2022-01-11 11:13           ` Benjamin Tissoires
2022-01-11 23:15             ` Limonciello, Mario
2022-01-12  8:33               ` Wolfram Sang
2022-01-12 12:21                 ` Miroslav Bendík
2022-01-12 22:54                   ` Limonciello, Mario
2022-01-15  9:39                     ` Miroslav Bendík
2022-01-15 13:46                       ` Limonciello, Mario
2022-01-15 18:10                         ` Miroslav Bendík
2022-01-17  8:39                         ` Miroslav Bendík
2022-01-17  9:08                           ` Hans de Goede
2022-01-23 17:25                             ` Miroslav Bendík
2022-01-12 12:31                 ` Hans de Goede
2022-01-30 13:14               ` Miroslav Bendík
2022-02-06 18:13               ` Miroslav Bendík

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.