All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH][2.6] Add command function to struct i2c_adapter
  2005-05-19  6:25 [Fwd: [PATCH][2.6] Add command function to struct i2c_adapter] Michael Hunold
@ 2005-05-19  6:25   ` Jean Delvare
  0 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2004-09-21 13:28 UTC (permalink / raw)
  To: Michael Hunold
  Cc: sensors, Linux Kernel Mailing List, Greg KH, Andrew Morton,
	Linus Torvalds

Hi Michael,

See my various questions inline.

> the attached patch adds a command function to struct i2c_adapter,
> similar to the command function that is already there for struct
> i2c_client.

I didne't even know that. Is this command function in struct i2c_client used
somewhere? What for?

> The reason behind this is as follows:
> In the DVB subsystem, the tuners are accessed via normal kernel i2c
> drivers. One big problem is, that tuners can be wired very differently
> depending on the surrounding hardware. Currently, we need to keep
> specific settings which are unique to a hardware design in the
> independent i2c tuner driver. This is both very ugly and makes it
> impossible to support DVB drivers which are not in the official Linux
> kernel tree, but could otherwise use in-kernel frontend driver.

What is the i2c tuner driver "independent" of? Do you simply mean that it
holds the common code for all DVB adapters?

> If the struct i2c_adapter has a command function, it would be possible
> to get additional informations from the adapter in the i2c client's
> attach_adapter() function *before* probing the device and guessing
> things like i2c addresses or other hardware settings.

I see what you want to do, but I don't exactly see how it solves your problem.
Your new command callback function will provide an adapter-specific interface
to adapter internal data. You will have to fill the data before you can access
it, so there still is hardware-specific data involved. Is your point that this
data would be located in (and split among) adapter drivers instead of the
common tuner driver as is now?

I am interested in your proposal because we (the sensors side of the i2c bus)
are facing a similar problem with hardware monitoring chips on motherboads.
The same chip can be wired differently on various motherboads, and most of the
time there is no way to guess (either because the hardware just doesn't
provide any way, or because the BIOS failed to do its job properly). We have
not come to any solution yet, and most of the time users have to use
user-space tools (such as i2cset) prior to loading the drivers. Looks like the
problem you are dealing with is of similar nature.

My initial thoughts about this were that we could use DMI data and/or PCI
information to identify systems, and trigger motherboard-specific code
whenever needed. It's really just a wild guess, I don't know if it is the
correct way. Wouldn't it work for you as well?

I would appreciate if you could show us some (pseudo)code with explanations on
what you have for now, and what you would have after the change. I have some
difficulties to understand what the change would actually change, most
probably because the video and sensors sides of the i2c subsystem work rather
differently.

On a completely different matter, what about the i2c subsystem class flags and
checking mechanism? You had come with a first step some months ago (adding a
class member to i2c clients), and your proposal (generalized check of i2c
client class against adapter class) looked very good to me, but then we did
not finish the job. What about it? I am willing to help on the sensors front
if you are going into this again someday. If I remember correctly, step 2 was
about clearing manual class checks and filling all class members, and step 3
was about implementing the generalized check in i2c-core. Am I right?

Thanks.

-- 
Jean Delvare
http://khali.linux-fr.org/


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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
  2005-05-19  6:25   ` Jean Delvare
@ 2005-05-19  6:25     ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-21 14:38 UTC (permalink / raw)
  To: Jean Delvare; +Cc: sensors, Linux Kernel Mailing List, Greg KH, linux-dvb

Hi,

(because I think this will be an in-depth discussion I trimmed the CC 
list a litte bit)

On 21.09.2004 15:28, Jean Delvare wrote:
>>the attached patch adds a command function to struct i2c_adapter,
>>similar to the command function that is already there for struct
>>i2c_client.

> I didne't even know that. Is this command function in struct i2c_client used
> somewhere? What for?

Please have a look at Video4Linux driver drivers/media/video/mxb.c. This 
driver needs various helper chipsets: tuner, tea6145c, tea6420, tda9840, 
saa7111.

For example the tea6415c is a simple video matrix chipset. If the user 
request a change of the input, the video matrix needs to be re-programmed.

For this, the tea6415 driver has the TEA6415C_SWITCH ioctl function, 
which is called through the i2c_client command() function.
 > mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);

Otherwise there would be no way the mxb driver could tell the tea6415c 
that the configuration should be changed.

>>The reason behind this is as follows:
>>In the DVB subsystem, the tuners are accessed via normal kernel i2c
>>drivers. One big problem is, that tuners can be wired very differently
>>depending on the surrounding hardware. Currently, we need to keep
>>specific settings which are unique to a hardware design in the
>>independent i2c tuner driver. This is both very ugly and makes it
>>impossible to support DVB drivers which are not in the official Linux
>>kernel tree, but could otherwise use in-kernel frontend driver.

> What is the i2c tuner driver "independent" of? Do you simply mean that it
> holds the common code for all DVB adapters?

The tuner is called frontend in dvb terms, because it holds more that 
just a simple tuner.

Some parts are hardware-independent and are in the right place in the 
frontend drivers. But manufacturers are free to use different plls (the 
actual tuners). Unfortunately, they nearly all sit on the same i2c 
address, are really dumb, write only and therefore not very distinguishable.

Currently the frontend drivers do a strcmp() on the adapter name. If it 
is "SkyStar2" for example, then it is a TechniSat card with a  Samsung 
TBMU24112IMB pll.

With that solution, it's not possible to support dvb drivers outside of 
the kernel which could theoretically use the in-kernel frontend drivers, 
because h/w dependend things need to coded into every frontend driver.

>>If the struct i2c_adapter has a command function, it would be possible
>>to get additional informations from the adapter in the i2c client's
>>attach_adapter() function *before* probing the device and guessing
>>things like i2c addresses or other hardware settings.

> I see what you want to do, but I don't exactly see how it solves your problem.
> Your new command callback function will provide an adapter-specific interface
> to adapter internal data.

Not adapter internal data, but frontend specific data, that only the 
manufacturer knows (which can be distinguished by subsystem pci ids).

 > You will have to fill the data before you can access
 > it, so there still is hardware-specific data involved. Is your point
 > that this
 > data would be located in (and split among) adapter drivers instead of
 > the
 > common tuner driver as is now?

Yes. With that approach, it's possible to support dvb drivers outside of 
the kernel, because all necessary information about the frontends is 
inside the dvb driver, not the frontend driver.

> I am interested in your proposal because we (the sensors side of the i2c bus)
> are facing a similar problem with hardware monitoring chips on motherboads.
> The same chip can be wired differently on various motherboads, and most of the
> time there is no way to guess (either because the hardware just doesn't
> provide any way, or because the BIOS failed to do its job properly). We have
> not come to any solution yet, and most of the time users have to use
> user-space tools (such as i2cset) prior to loading the drivers. Looks like the
> problem you are dealing with is of similar nature.

Yes, it's basically the same.

> My initial thoughts about this were that we could use DMI data and/or PCI
> information to identify systems, and trigger motherboard-specific code
> whenever needed. It's really just a wild guess, I don't know if it is the
> correct way. Wouldn't it work for you as well?

This is how it will work. In our case, we only need pci ids, but it's 
possible to use other information sources as well.

Let's say the user loads the stv0299 frontend driver and later the 
dvb-ttpci device driver.

The dvb-ttpci driver exports an i2c_adapter, the stv0299 
i2c_attach_adapter() function will be called. Ideally, if this isn't a 
bus from the digitial tv subsystem, then bail out (This needs to be 
implemented, see below).

If we are on a digital tv i2c bus the stv0299 uses the i2c adapter 
command() callback and asks the i2c adapter, if this frontend can be on 
that bus at all and asks for further informations.

dvb-ttpci knows the pci ids and can tell different hardware versions. 
For example, cable dvb cards have different pci ids than satellite dvb 
cards. The stv0299 is a satellite frontend, so if the bus is on a dvb 
cable card then dvb-ttpci can simply tell the stv0299 driver not to do 
anything.

If the stv0299 can be found on that system in theory, either the correct 
hardware stv0299 dependent informations are supplied completely or 
probing informations are supplied.

> I would appreciate if you could show us some (pseudo)code with explanations on
> what you have for now, and what you would have after the change. I have some
> difficulties to understand what the change would actually change, most
> probably because the video and sensors sides of the i2c subsystem work rather
> differently.

Please have a look at drivers/media/dvb/frontends/stv0299.c

At the top you'll notice a lot of defines:
#define PHILIPS_SU1278_TUA      3 // SU1278 with TUA6100 synth

In lots of functions there are switch/case statements to distinguish 
different plls, for example in pll_set_tv_freq().  stv0299_init() is 
ugly, too. The init-data for different hardware is hardcoded into the 
frontend driver. *shiver*

With the command() function, probe_tuner() with the ugly strcmp() stuff 
and i2c probing can be killed completely.

In other places, common i2c_adapter commands can be used to pull 
frontend device specific data from the dvb device (for example frequency 
boundaries) or trigger h/w dependend thinks that only the dvb driver 
knows, like setting a frequency in the pll with command(SET_PLL).

Sorry, I just have some proof-of-concept code, that doesn't use all the 
things I explained above. Some dvb people would like to give up the 
strong separation due to the kernel i2c interface and have something 
more "dvbish".

> On a completely different matter, what about the i2c subsystem class flags and
> checking mechanism? You had come with a first step some months ago (adding a
> class member to i2c clients), and your proposal (generalized check of i2c
> client class against adapter class) looked very good to me, but then we did
> not finish the job. What about it? I am willing to help on the sensors front
> if you are going into this again someday. If I remember correctly, step 2 was
> about clearing manual class checks and filling all class members, and step 3
> was about implementing the generalized check in i2c-core. Am I right?

I'll answer that in a separate mail.

> Thanks.

CU
Michael.

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

* Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter
  2005-05-19  6:25   ` Jean Delvare
@ 2005-05-19  6:25     ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-21 17:41 UTC (permalink / raw)
  To: Jean Delvare; +Cc: sensors, Linux Kernel Mailing List, Greg KH

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

Hi,

On 21.09.2004 15:28, Jean Delvare wrote:
> On a completely different matter, what about the i2c subsystem class flags and
> checking mechanism? You had come with a first step some months ago (adding a
> class member to i2c clients), and your proposal (generalized check of i2c
> client class against adapter class) looked very good to me, but then we did
> not finish the job. What about it? 

I was unsure about the .class entries for some of the clients, then 
didn't find the time to investigate further and from then on the patches 
are bit-rotting on my harddisc. ;-(

> I am willing to help on the sensors front
> if you are going into this again someday. If I remember correctly, step 2 was
> about clearing manual class checks and filling all class members, and step 3
> was about implementing the generalized check in i2c-core. Am I right?

Yes, right. I've cleaned up the patches and attached them to this mail. 
Unfortunately, they only apply to 2.6.8(.1), but not 2.6.9-rc2-mm1. This 
is because SMBUS has been renamed to HWMON IIRC.

Please have a look and tell me what you think. The big problem will be, 
that we cannot test all configurations, so it's possible that some 
devices won't be recognized anymore, because the .class entries don't match.

Patches 1-3 are straight forward. For patches 4-7 I once created the 
following list:

==>4
#drivers/ieee1394/pcilynx.c => I2C_CLASS_NONE
#drivers/macintosh/therm_adt746x.c => I2C_CLASS_HWMON
#drivers/macintosh/therm_pm72.c => I2C_CLASS_HWMON
#drivers/macintosh/therm_windtunnel.c => I2C_CLASS_HWMON
#drivers/acorn/char/pcf8583.c => I2C_CLASS_ALL
#drivers/acorn/char/i2c.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-keywest.c: => I2C_CLASS_HWMON | I2C_CLASS_SOUND;
#sound/ppc/keywest.c => I2C_CLASS_SOUND
#sound/oss/dmasound/dac3550a.c => I2C_CLASS_SOUND
#sound/oss/dmasound/tas_common.c => I2C_CLASS_SOUND

==>5
#drivers/i2c/algos/i2c-algo-pcf.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-elektor.c => I2C_CLASS_ALL
#drivers/video/aty/radeon_i2c.c => I2C_CLASS_NONE
#drivers/video/matrox/i2c-matroxfb.c => I2C_CLASS_DDC and 
I2C_CLASS_TV_ANALOG
#drivers/video/matrox/matroxfb_maven.c => I2C_CLASS_TV_ANALOG
#drivers/media/video/zoran_card.c => I2C_CLASS_TV_ANALOG
#drivers/media/video/ir-kbd-i2c.c => I2C_CLASS_TV_ANALOG | 
I2C_CLASS_TV_DIGITAL
#drivers/media/dvb/bt8xx/dvb-bt8xx.c => I2C_CLASS_ALL

==>6
#drivers/i2c/busses/i2c-ibm_iic.c: => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-iop3xx.c:=> I2C_CLASS_ALL
#drivers/i2c/busses/scx200_i2c.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-ite.c => I2C_CLASS_ALL
(drivers/i2c/algos/i2c-algo-ite.c:)

==>7
#drivers/i2c/busses/i2c-frodo.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-i810.c => I2C_CLASS_ALL + I2C_CLASS_DDC
#drivers/i2c/busses/i2c-prosavage.c => I2C_CLASS_ALL + I2C_CLASS_DDC
#drivers/i2c/busses/i2c-savage4.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-ixp4xx.c => I2C_CLASS_ALL, doesn't compile!?
#drivers/i2c/busses/i2c-hydra.c => I2C_CLASS_HWMON

> Thanks.

CU
Michael.


[-- Attachment #2: 01-drivers-media-video.diff --]
[-- Type: text/plain, Size: 6901 bytes --]

diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/adv7170.c linux-2.6-6-rc3-mm2/drivers/media/video/adv7170.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/adv7170.c	2004-05-09 11:03:04.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/adv7170.c	2004-05-09 11:28:12.000000000 +0200
@@ -516,6 +516,7 @@
 
 	.id = I2C_DRIVERID_ADV7170,
 	.flags = I2C_DF_NOTIFY,
+ 	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = adv7170_attach_adapter,
 	.detach_client = adv7170_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/adv7175.c linux-2.6-6-rc3-mm2/drivers/media/video/adv7175.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/adv7175.c	2004-05-09 11:03:04.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/adv7175.c	2004-05-09 11:27:55.000000000 +0200
@@ -538,6 +538,7 @@
 
 	.id = I2C_DRIVERID_ADV7175,
 	.flags = I2C_DF_NOTIFY,
+ 	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = adv7175_attach_adapter,
 	.detach_client = adv7175_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt819.c linux-2.6-6-rc3-mm2/drivers/media/video/bt819.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt819.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/bt819.c	2004-05-09 11:24:22.000000000 +0200
@@ -642,6 +642,7 @@
 
 	.id = I2C_DRIVERID_BT819,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = bt819_attach_adapter,
 	.detach_client = bt819_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt856.c linux-2.6-6-rc3-mm2/drivers/media/video/bt856.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt856.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/bt856.c	2004-05-09 11:23:22.000000000 +0200
@@ -423,6 +423,7 @@
 
 	.id = I2C_DRIVERID_BT856,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = bt856_attach_adapter,
 	.detach_client = bt856_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7110.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7110.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7110.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7110.c	2004-05-09 11:22:57.000000000 +0200
@@ -599,6 +599,7 @@
 
 	.id = I2C_DRIVERID_SAA7110,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = saa7110_attach_adapter,
 	.detach_client = saa7110_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7111.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7111.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7111.c	2004-05-09 11:06:43.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7111.c	2004-05-09 11:24:54.000000000 +0200
@@ -608,7 +608,8 @@
 
 	.id = I2C_DRIVERID_SAA7111A,
 	.flags = I2C_DF_NOTIFY,
-
+	.class = I2C_CLASS_TV_ANALOG,
+	
 	.attach_adapter = saa7111_attach_adapter,
 	.detach_client = saa7111_detach_client,
 	.command = saa7111_command,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7114.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7114.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7114.c	2004-05-09 11:03:04.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7114.c	2004-05-09 11:27:15.000000000 +0200
@@ -1222,6 +1222,7 @@
 
 	.id = I2C_DRIVERID_SAA7114,
 	.flags = I2C_DF_NOTIFY,
+ 	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = saa7114_attach_adapter,
 	.detach_client = saa7114_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7185.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7185.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7185.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7185.c	2004-05-09 11:23:55.000000000 +0200
@@ -505,6 +505,7 @@
 
 	.id = I2C_DRIVERID_SAA7185B,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = saa7185_attach_adapter,
 	.detach_client = saa7185_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9840.c linux-2.6-6-rc3-mm2/drivers/media/video/tda9840.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9840.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tda9840.c	2004-05-09 11:26:35.000000000 +0200
@@ -263,6 +263,7 @@
 	.name		= "tda9840 driver",
 	.id		= I2C_DRIVERID_TDA9840,
 	.flags		= I2C_DF_NOTIFY,
+ 	.class 		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = tda9840_attach,
         .detach_client	= tda9840_detach,
         .command	= tda9840_command,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tea6415c.c linux-2.6-6-rc3-mm2/drivers/media/video/tea6415c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tea6415c.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tea6415c.c	2004-05-09 11:26:52.000000000 +0200
@@ -212,6 +212,7 @@
 	.name		= "tea6415c driver",
 	.id		= I2C_DRIVERID_TEA6415C,
 	.flags		= I2C_DF_NOTIFY,
+ 	.class 		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = tea6415c_attach,
         .detach_client	= tea6415c_detach,
         .command	= tea6415c_command,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tea6420.c linux-2.6-6-rc3-mm2/drivers/media/video/tea6420.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tea6420.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tea6420.c	2004-05-09 11:26:09.000000000 +0200
@@ -192,8 +192,9 @@
 	.name		= "tea6420 driver",
 	.id		= I2C_DRIVERID_TEA6420,
 	.flags		= I2C_DF_NOTIFY,
-        .attach_adapter = tea6420_attach,
+ 	.class 		= I2C_CLASS_TV_ANALOG,
+	.attach_adapter = tea6420_attach,
         .detach_client	= tea6420_detach,
         .command	= tea6420_command,
 };
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tuner-3036.c linux-2.6-6-rc3-mm2/drivers/media/video/tuner-3036.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tuner-3036.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tuner-3036.c	2004-05-09 11:25:25.000000000 +0200
@@ -185,6 +185,7 @@
 	.name		=	"sab3036",
 	.id		=	I2C_DRIVERID_SAB3036,
         .flags		=	I2C_DF_NOTIFY,
+	.class 		=	I2C_CLASS_TV_ANALOG,
 	.attach_adapter =	tuner_probe,
 	.detach_client  =	tuner_detach,
 	.command	=	tuner_command
@@ -200,8 +201,7 @@
 int __init
 tuner3036_init(void)
 {
-	i2c_add_driver(&i2c_driver_tuner);
-	return 0;
+	return i2c_add_driver(&i2c_driver_tuner);
 }
 
 void __exit
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/vpx3220.c linux-2.6-6-rc3-mm2/drivers/media/video/vpx3220.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/vpx3220.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/vpx3220.c	2004-05-09 11:27:33.000000000 +0200
@@ -731,6 +731,7 @@
 
 	.id = I2C_DRIVERID_VPX3220,
 	.flags = I2C_DF_NOTIFY,
+ 	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = vpx3220_attach_adapter,
 	.detach_client = vpx3220_detach_client,

[-- Attachment #3: 02-drivers-media-video-2.diff --]
[-- Type: text/plain, Size: 13142 bytes --]

diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt832.c linux-2.6-6-rc3-mm2/drivers/media/video/bt832.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt832.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/bt832.c	2004-05-09 14:49:58.000000000 +0200
@@ -197,9 +197,7 @@
 
 static int bt832_probe(struct i2c_adapter *adap)
 {
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, bt832_attach);
-	return 0;
+	return i2c_probe(adap, &addr_data, bt832_attach);
 }
 
 static int bt832_detach(struct i2c_client *client)
@@ -243,6 +241,7 @@
         .name           = "i2c bt832 driver",
         .id             = -1, /* FIXME */
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = bt832_probe,
         .detach_client  = bt832_detach,
         .command        = bt832_command,
@@ -257,8 +256,7 @@
 
 int bt832_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void bt832_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/msp3400.c linux-2.6-6-rc3-mm2/drivers/media/video/msp3400.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/msp3400.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/msp3400.c	2004-05-09 14:48:30.000000000 +0200
@@ -1222,6 +1222,7 @@
         .name           = "i2c msp3400 driver",
         .id             = I2C_DRIVERID_MSP3400,
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = msp_probe,
         .detach_client  = msp_detach,
         .command        = msp_command,
@@ -1353,19 +1354,7 @@
 
 static int msp_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, msp_attach);
-#else
-	switch (adap->id) {
-	case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	//case I2C_ALGO_SAA7134:
-		return i2c_probe(adap, &addr_data, msp_attach);
-		break;
-	}
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, msp_attach);
 }
 
 static void msp_wake_thread(struct i2c_client *client)
@@ -1558,8 +1547,7 @@
 
 static int msp3400_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void msp3400_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa5246a.c linux-2.6-6-rc3-mm2/drivers/media/video/saa5246a.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa5246a.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa5246a.c	2004-05-09 14:52:53.000000000 +0200
@@ -143,9 +143,7 @@
  */
 static int saa5246a_probe(struct i2c_adapter *adap)
 {
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, saa5246a_attach);
-	return 0;
+	return i2c_probe(adap, &addr_data, saa5246a_attach);
 }
 
 static int saa5246a_detach(struct i2c_client *client)
@@ -174,6 +172,7 @@
 	.name 		= IF_NAME,		/* name */
 	.id 		= I2C_DRIVERID_SAA5249, /* in i2c.h */
 	.flags 		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
 	.attach_adapter = saa5246a_probe,
 	.detach_client  = saa5246a_detach,
 	.command 	= saa5246a_command
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa5249.c linux-2.6-6-rc3-mm2/drivers/media/video/saa5249.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa5249.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa5249.c	2004-05-09 14:50:30.000000000 +0200
@@ -219,9 +219,7 @@
  
 static int saa5249_probe(struct i2c_adapter *adap)
 {
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, saa5249_attach);
-	return 0;
+	return i2c_probe(adap, &addr_data, saa5249_attach);
 }
 
 static int saa5249_detach(struct i2c_client *client)
@@ -249,6 +247,7 @@
 	.name 		= IF_NAME,		/* name */
 	.id 		= I2C_DRIVERID_SAA5249, /* in i2c.h */
 	.flags 		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
 	.attach_adapter = saa5249_probe,
 	.detach_client  = saa5249_detach,
 	.command 	= saa5249_command
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7134/saa6752hs.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7134/saa6752hs.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7134/saa6752hs.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7134/saa6752hs.c	2004-05-09 14:47:01.000000000 +0200
@@ -335,9 +335,7 @@
 
 static int saa6752hs_probe(struct i2c_adapter *adap)
 {
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, saa6752hs_attach);
-	return 0;
+	return i2c_probe(adap, &addr_data, saa6752hs_attach);
 }
 
 static int saa6752hs_detach(struct i2c_client *client)
@@ -376,6 +373,7 @@
         .name           = "i2c saa6752hs MPEG encoder",
         .id             = I2C_DRIVERID_SAA6752HS,
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = saa6752hs_probe,
         .detach_client  = saa6752hs_detach,
         .command        = saa6752hs_command,
@@ -390,8 +388,7 @@
 
 static int saa6752hs_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void saa6752hs_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda7432.c linux-2.6-6-rc3-mm2/drivers/media/video/tda7432.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda7432.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tda7432.c	2004-05-09 14:49:17.000000000 +0200
@@ -338,14 +338,7 @@
 
 static int tda7432_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, tda7432_attach);
-#else
-	if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
-		return i2c_probe(adap, &addr_data, tda7432_attach);
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, tda7432_attach);
 }
 
 static int tda7432_detach(struct i2c_client *client)
@@ -520,6 +513,7 @@
         .name            = "i2c tda7432 driver",
 	.id              = I2C_DRIVERID_TDA7432,
         .flags           = I2C_DF_NOTIFY,
+	.class		 = I2C_CLASS_TV_ANALOG,
 	.attach_adapter  = tda7432_probe,
         .detach_client   = tda7432_detach,
         .command         = tda7432_command,
@@ -538,8 +532,7 @@
 		printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n");
 		return -EINVAL;
 	}
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tda7432_fini(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9875.c linux-2.6-6-rc3-mm2/drivers/media/video/tda9875.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9875.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tda9875.c	2004-05-09 14:48:00.000000000 +0200
@@ -272,14 +272,7 @@
 
 static int tda9875_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, tda9875_attach);
-#else
-	if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
-		return i2c_probe(adap, &addr_data, tda9875_attach);
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, tda9875_attach);
 }
 
 static int tda9875_detach(struct i2c_client *client)
@@ -391,6 +384,7 @@
         .name           = "i2c tda9875 driver",
         .id             = I2C_DRIVERID_TDA9875,
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
 	.attach_adapter = tda9875_probe,
         .detach_client  = tda9875_detach,
         .command        = tda9875_command,
@@ -405,8 +399,7 @@
 
 static int tda9875_init(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tda9875_fini(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9887.c linux-2.6-6-rc3-mm2/drivers/media/video/tda9887.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9887.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tda9887.c	2004-05-09 14:46:31.000000000 +0200
@@ -370,19 +370,7 @@
 
 static int tda9887_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, tda9887_attach);
-#else
-	switch (adap->id) {
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
-	case I2C_ALGO_SAA7134:
-		return i2c_probe(adap, &addr_data, tda9887_attach);
-		break;
-	}
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, tda9887_attach);
 }
 
 static int tda9887_detach(struct i2c_client *client)
@@ -447,6 +435,7 @@
         .name           = "i2c tda9887 driver",
         .id             = -1, /* FIXME */
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = tda9887_probe,
         .detach_client  = tda9887_detach,
         .command        = tda9887_command,
@@ -460,8 +449,7 @@
 
 static int tda9887_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tda9887_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tuner.c linux-2.6-6-rc3-mm2/drivers/media/video/tuner.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tuner.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tuner.c	2004-05-09 14:51:10.000000000 +0200
@@ -1067,21 +1067,7 @@
 	}
 	this_adap = 0;
 
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, tuner_attach);
-#else
-	switch (adap->id) {
-	case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
-	case I2C_ALGO_SAA7134:
-	case I2C_ALGO_SAA7146:
-		return i2c_probe(adap, &addr_data, tuner_attach);
-		break;
-	}
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, tuner_attach);
 }
 
 static int tuner_detach(struct i2c_client *client)
@@ -1184,6 +1170,7 @@
         .name           = "i2c TV tuner driver",
         .id             = I2C_DRIVERID_TUNER,
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = tuner_probe,
         .detach_client  = tuner_detach,
         .command        = tuner_command,
@@ -1197,8 +1184,7 @@
 
 static int tuner_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tuner_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tvaudio.c linux-2.6-6-rc3-mm2/drivers/media/video/tvaudio.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tvaudio.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tvaudio.c	2004-05-09 14:47:38.000000000 +0200
@@ -1497,18 +1497,7 @@
 
 static int chip_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, chip_attach);
-#else
-	switch (adap->id) {
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
-	case I2C_ALGO_SAA7134:
-		return i2c_probe(adap, &addr_data, chip_attach);
-	}
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, chip_attach);
 }
 
 static int chip_detach(struct i2c_client *client)
@@ -1639,6 +1628,7 @@
         .name            = "generic i2c audio driver",
         .id              = I2C_DRIVERID_TVAUDIO,
         .flags           = I2C_DF_NOTIFY,
+	.class		 = I2C_CLASS_TV_ANALOG,
         .attach_adapter  = chip_probe,
         .detach_client   = chip_detach,
         .command         = chip_command,
@@ -1659,8 +1649,7 @@
 	for (desc = chiplist; desc->name != NULL; desc++)
 		printk("%s%s", (desc == chiplist) ? "" : ",",desc->name);
 	printk("\n");
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void audiochip_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tvmixer.c linux-2.6-6-rc3-mm2/drivers/media/video/tvmixer.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tvmixer.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tvmixer.c	2004-05-09 14:52:10.000000000 +0200
@@ -232,6 +232,7 @@
 	.flags           = I2C_DF_NOTIFY,
         .detach_adapter  = tvmixer_adapters,
 #endif
+	.class		 = I2C_CLASS_TV_ANALOG,
         .attach_adapter  = tvmixer_adapters,
         .detach_client   = tvmixer_clients,
 };
@@ -263,23 +264,6 @@
 	struct video_audio va;
 	int i,minor;
 
-#ifdef I2C_CLASS_TV_ANALOG
-	if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
-		return -1;
-#else
-	/* TV card ??? */
-	switch (client->adapter->id) {
-	case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
-		/* ok, have a look ... */
-		break;
-	default:
-		/* ignore that one */
-		return -1;
-	}
-#endif
-
 	/* unregister ?? */
 	for (i = 0; i < DEV_MAX; i++) {
 		if (devices[i].dev == client) {
@@ -334,8 +318,7 @@
 	
 	for (i = 0; i < DEV_MAX; i++)
 		devices[i].minor = -1;
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tvmixer_cleanup_module(void)

[-- Attachment #4: 03-drivers-i2c-chips.diff --]
[-- Type: text/plain, Size: 12163 bytes --]

diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/adm1021.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/adm1021.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/adm1021.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/adm1021.c	2004-05-09 16:17:00.000000000 +0200
@@ -144,6 +144,7 @@
 	.name		= "adm1021",
 	.id		= I2C_DRIVERID_ADM1021,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= adm1021_attach_adapter,
 	.detach_client	= adm1021_detach_client,
 };
@@ -200,8 +201,6 @@
 
 static int adm1021_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, adm1021_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/asb100.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/asb100.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/asb100.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/asb100.c	2004-05-09 16:13:42.000000000 +0200
@@ -233,6 +233,7 @@
 	.name		= "asb100",
 	.id		= I2C_DRIVERID_ASB100,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= asb100_attach_adapter,
 	.detach_client	= asb100_detach_client,
 };
@@ -609,8 +610,6 @@
  */
 static int asb100_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, asb100_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/ds1621.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/ds1621.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/ds1621.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/ds1621.c	2004-05-09 16:11:42.000000000 +0200
@@ -92,6 +92,7 @@
 	.name		= "ds1621",
 	.id		= I2C_DRIVERID_DS1621,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= ds1621_attach_adapter,
 	.detach_client	= ds1621_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/eeprom.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/eeprom.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/eeprom.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/eeprom.c	2004-05-09 16:11:59.000000000 +0200
@@ -82,6 +82,7 @@
 	.name		= "eeprom",
 	.id		= I2C_DRIVERID_EEPROM,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= eeprom_attach_adapter,
 	.detach_client	= eeprom_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/fscher.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/fscher.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/fscher.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/fscher.c	2004-05-09 16:13:00.000000000 +0200
@@ -124,6 +124,7 @@
 	.name		= "fscher",
 	.id		= I2C_DRIVERID_FSCHER,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= fscher_attach_adapter,
 	.detach_client	= fscher_detach_client,
 };
@@ -293,8 +294,6 @@
 
 static int fscher_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, fscher_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/gl518sm.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/gl518sm.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/gl518sm.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/gl518sm.c	2004-05-09 16:12:21.000000000 +0200
@@ -156,6 +156,7 @@
 	.name		= "gl518sm",
 	.id		= I2C_DRIVERID_GL518,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= gl518_attach_adapter,
 	.detach_client	= gl518_detach_client,
 };
@@ -335,8 +336,6 @@
 
 static int gl518_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, gl518_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/it87.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/it87.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/it87.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/it87.c	2004-05-09 16:16:14.000000000 +0200
@@ -173,6 +173,7 @@
 	.name		= "it87",
 	.id		= I2C_DRIVERID_IT87,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= it87_attach_adapter,
 	.detach_client	= it87_detach_client,
 };
@@ -500,8 +501,6 @@
      * when a new adapter is inserted (and it87_driver is still present) */
 static int it87_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, it87_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm78.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm78.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm78.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm78.c	2004-05-09 16:15:57.000000000 +0200
@@ -229,6 +229,7 @@
 	.name		= "lm78",
 	.id		= I2C_DRIVERID_LM78,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= lm78_attach_adapter,
 	.detach_client	= lm78_detach_client,
 };
@@ -488,8 +489,6 @@
      * when a new adapter is inserted (and lm78_driver is still present) */
 static int lm78_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, lm78_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm80.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm80.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm80.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm80.c	2004-05-09 16:15:28.000000000 +0200
@@ -156,6 +156,7 @@
 	.name		= "lm80",
 	.id		= I2C_DRIVERID_LM80,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= lm80_attach_adapter,
 	.detach_client	= lm80_detach_client,
 };
@@ -376,8 +377,6 @@
 
 static int lm80_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, lm80_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm83.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm83.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm83.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm83.c	2004-05-09 16:15:08.000000000 +0200
@@ -125,6 +125,7 @@
 	.name		= "lm83",
 	.id		= I2C_DRIVERID_LM83,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= lm83_attach_adapter,
 	.detach_client	= lm83_detach_client,
 };
@@ -216,8 +217,6 @@
 
 static int lm83_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, lm83_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm85.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm85.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm85.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm85.c	2004-05-09 16:14:53.000000000 +0200
@@ -403,6 +403,7 @@
 	.name           = "lm85",
 	.id             = I2C_DRIVERID_LM85,
 	.flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter = lm85_attach_adapter,
 	.detach_client  = lm85_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm90.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm90.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm90.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm90.c	2004-05-09 16:14:33.000000000 +0200
@@ -146,6 +146,7 @@
 	.name		= "lm90",
 	.id		= I2C_DRIVERID_LM90,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= lm90_attach_adapter,
 	.detach_client	= lm90_detach_client,
 };
@@ -274,8 +275,6 @@
 
 static int lm90_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, lm90_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8574.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8574.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8574.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8574.c	2004-05-09 16:10:36.000000000 +0200
@@ -73,6 +73,7 @@
 	.name		= "pcf8574",
 	.id		= I2C_DRIVERID_PCF8574,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= pcf8574_attach_adapter,
 	.detach_client	= pcf8574_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8591.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8591.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8591.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8591.c	2004-05-09 16:10:09.000000000 +0200
@@ -95,6 +95,7 @@
 	.name		= "pcf8591",
 	.id		= I2C_DRIVERID_PCF8591,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= pcf8591_attach_adapter,
 	.detach_client	= pcf8591_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/via686a.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/via686a.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/via686a.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/via686a.c	2004-05-09 16:16:46.000000000 +0200
@@ -586,6 +586,7 @@
 	.name		= "via686a",
 	.id		= I2C_DRIVERID_VIA686A,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= via686a_attach_adapter,
 	.detach_client	= via686a_detach_client,
 };
@@ -594,8 +595,6 @@
 /* This is called when the module is loaded */
 static int via686a_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, via686a_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83627hf.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83627hf.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83627hf.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83627hf.c	2004-05-09 16:11:27.000000000 +0200
@@ -331,6 +331,7 @@
 	.name		= "w83627hf",
 	.id		= I2C_DRIVERID_W83627HF,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= w83627hf_attach_adapter,
 	.detach_client	= w83627hf_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83781d.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83781d.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83781d.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83781d.c	2004-05-09 16:17:18.000000000 +0200
@@ -281,6 +281,7 @@
 	.name = "w83781d",
 	.id = I2C_DRIVERID_W83781D,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_HWMON,
 	.attach_adapter = w83781d_attach_adapter,
 	.detach_client = w83781d_detach_client,
 };
@@ -905,8 +906,6 @@
 static int
 w83781d_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, w83781d_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83l785ts.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83l785ts.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83l785ts.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83l785ts.c	2004-05-09 16:13:22.000000000 +0200
@@ -96,6 +96,7 @@
 	.name		= "w83l785ts",
 	.id		= I2C_DRIVERID_W83L785TS,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= w83l785ts_attach_adapter,
 	.detach_client	= w83l785ts_detach_client,
 };
@@ -145,8 +146,6 @@
 
 static int w83l785ts_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, w83l785ts_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/i2c-dev.c linux-2.6-6-rc3-mm2/drivers/i2c/i2c-dev.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/i2c-dev.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/i2c-dev.c	2004-05-09 16:06:33.000000000 +0200
@@ -500,6 +500,7 @@
 	.name		= "dev_driver",
 	.id		= I2C_DRIVERID_I2CDEV,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_ALL,
 	.attach_adapter	= i2cdev_attach_adapter,
 	.detach_adapter	= i2cdev_detach_adapter,
 	.detach_client	= i2cdev_detach_client,

[-- Attachment #5: 04-misc.diff --]
[-- Type: text/plain, Size: 6029 bytes --]

diff -ura xx-linux-2.6-6-rc3-mm2/drivers/acorn/char/i2c.c linux-2.6-6-rc3-mm2/drivers/acorn/char/i2c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/acorn/char/i2c.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/acorn/char/i2c.c	2004-05-09 16:31:58.000000000 +0200
@@ -345,6 +345,7 @@
 static struct i2c_adapter ioc_ops = {
 	.id			= I2C_HW_B_IOC,
 	.algo_data		= &ioc_data,
+	.class			= I2C_CLASS_ALL,
 	.client_register	= ioc_client_reg,
 	.client_unregister	= ioc_client_unreg,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/acorn/char/pcf8583.c linux-2.6-6-rc3-mm2/drivers/acorn/char/pcf8583.c
--- xx-linux-2.6-6-rc3-mm2/drivers/acorn/char/pcf8583.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/acorn/char/pcf8583.c	2004-05-09 16:33:20.000000000 +0200
@@ -227,6 +227,7 @@
 	.name		= "PCF8583",
 	.id		= I2C_DRIVERID_PCF8583,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_ALL, /* fixme: add another I2C_CLASS_xxx entry for Acorn? */
 	.attach_adapter	= pcf8583_probe,
 	.detach_client	= pcf8583_detach,
 	.command	= pcf8583_command
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-keywest.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-keywest.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-keywest.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-keywest.c	2004-05-09 16:37:41.000000000 +0200
@@ -619,6 +619,7 @@
 		chan->iface = iface;
 		chan->chan_no = i;
 		chan->adapter.id = I2C_ALGO_SMBUS;
+		chan->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SOUND;
 		chan->adapter.algo = &keywest_algorithm;
 		chan->adapter.algo_data = NULL;
 		chan->adapter.client_register = NULL;
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/ieee1394/pcilynx.c linux-2.6-6-rc3-mm2/drivers/ieee1394/pcilynx.c
--- xx-linux-2.6-6-rc3-mm2/drivers/ieee1394/pcilynx.c	2004-05-09 11:05:30.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/ieee1394/pcilynx.c	2004-05-09 16:42:30.000000000 +0200
@@ -1799,6 +1799,7 @@
                 i2c_adapter = bit_ops;
                 i2c_adapter_data = bit_data;
                 i2c_adapter.algo_data = &i2c_adapter_data;
+		i2c_adapter.class = I2C_CLASS_NONE;
                 i2c_adapter_data.data = lynx;
 
 		PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d",
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_adt746x.c linux-2.6-6-rc3-mm2/drivers/macintosh/therm_adt746x.c
--- xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_adt746x.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/macintosh/therm_adt746x.c	2004-05-09 16:30:02.000000000 +0200
@@ -164,6 +164,7 @@
 	.name		="Apple Thermostat ADT746x",
 	.id		=0xDEAD7467,
 	.flags		=I2C_DF_NOTIFY,
+	.class		=I2C_CLASS_HWMON,
 	.attach_adapter	=&attach_thermostat,
 	.detach_adapter	=&detach_thermostat,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_pm72.c linux-2.6-6-rc3-mm2/drivers/macintosh/therm_pm72.c
--- xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_pm72.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/macintosh/therm_pm72.c	2004-05-09 16:29:32.000000000 +0200
@@ -142,6 +142,7 @@
 	.name		= "therm_pm72",
 	.id		= 0xDEADBEEF,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= therm_pm72_attach,
 	.detach_adapter	= therm_pm72_detach,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_windtunnel.c linux-2.6-6-rc3-mm2/drivers/macintosh/therm_windtunnel.c
--- xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_windtunnel.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/macintosh/therm_windtunnel.c	2004-05-09 16:29:13.000000000 +0200
@@ -357,6 +357,7 @@
 	.name		= "Apple G4 Thermostat/Fan",
 	.id		= I2C_DRIVERID_G4FAN,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter = &do_attach,
 	.detach_client	= &do_detach,
 	.command	= NULL,
diff -ura xx-linux-2.6-6-rc3-mm2/include/linux/i2c.h linux-2.6-6-rc3-mm2/include/linux/i2c.h
--- xx-linux-2.6-6-rc3-mm2/include/linux/i2c.h	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/include/linux/i2c.h	2004-05-09 16:42:13.000000000 +0200
@@ -285,7 +285,8 @@
 #define I2C_CLIENT_TEN	0x10			/* we have a ten bit chip address	*/
 						/* Must equal I2C_M_TEN below */
 
-/* i2c adapter classes (bitmask) */
+/* i2c classes (bitmask) */
+#define I2C_CLASS_NONE		0	/* none, don't use */
 #define I2C_CLASS_HWMON		(1<<0)	/* lm_sensors, ... */
 #define I2C_CLASS_TV_ANALOG	(1<<1)	/* bttv + friends */
 #define I2C_CLASS_TV_DIGITAL	(1<<2)	/* dvb cards */
diff -ura xx-linux-2.6-6-rc3-mm2/sound/oss/dmasound/dac3550a.c linux-2.6-6-rc3-mm2/sound/oss/dmasound/dac3550a.c
--- xx-linux-2.6-6-rc3-mm2/sound/oss/dmasound/dac3550a.c	2004-05-09 11:04:50.000000000 +0200
+++ linux-2.6-6-rc3-mm2/sound/oss/dmasound/dac3550a.c	2004-05-09 16:38:47.000000000 +0200
@@ -47,6 +47,7 @@
 	.name			= "DAC3550A driver  V " DACA_VERSION,
 	.id			= I2C_DRIVERID_DACA,
 	.flags			= I2C_DF_NOTIFY,
+	.class			= I2C_CLASS_SOUND,
 	.attach_adapter		= daca_attach_adapter,
 	.detach_client		= daca_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/sound/oss/dmasound/tas_common.c linux-2.6-6-rc3-mm2/sound/oss/dmasound/tas_common.c
--- xx-linux-2.6-6-rc3-mm2/sound/oss/dmasound/tas_common.c	2004-05-09 11:04:50.000000000 +0200
+++ linux-2.6-6-rc3-mm2/sound/oss/dmasound/tas_common.c	2004-05-09 16:39:01.000000000 +0200
@@ -50,6 +50,7 @@
 	.owner		= THIS_MODULE,
 	.name		= "tas",
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_SOUND,
 	.attach_adapter	= tas_attach_adapter,
 	.detach_client	= tas_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/sound/ppc/keywest.c linux-2.6-6-rc3-mm2/sound/ppc/keywest.c
--- xx-linux-2.6-6-rc3-mm2/sound/ppc/keywest.c	2004-05-09 11:06:53.000000000 +0200
+++ linux-2.6-6-rc3-mm2/sound/ppc/keywest.c	2004-05-09 16:38:03.000000000 +0200
@@ -44,6 +44,7 @@
 	.name = "PMac Keywest Audio",
 	.id = I2C_DRIVERID_KEYWEST,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_SOUND,
 	.attach_adapter = &keywest_attach_adapter,
 	.detach_client = &keywest_detach_client,
 };

[-- Attachment #6: 05-unclear.diff --]
[-- Type: text/plain, Size: 6322 bytes --]

diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/algos/i2c-algo-pcf.c linux-2.6-6-rc3-mm2/drivers/i2c/algos/i2c-algo-pcf.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/algos/i2c-algo-pcf.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/algos/i2c-algo-pcf.c	2004-05-09 18:00:47.000000000 +0200
@@ -449,7 +449,8 @@
 
 	adap->id |= pcf_algo.id;
 	adap->algo = &pcf_algo;
-
+	adap->class = I2C_CLASS_ALL;
+	
 	adap->timeout = 100;		/* default values, should	*/
 	adap->retries = 3;		/* be replaced by defines	*/
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-elektor.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-elektor.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-elektor.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-elektor.c	2004-05-09 17:57:16.000000000 +0200
@@ -171,6 +171,7 @@
 	.owner		= THIS_MODULE,
 	.id		= I2C_HW_P_ELEK,
 	.algo_data	= &pcf_isa_data,
+	.class		= I2C_CLASS_ALL,
 	.name		= "PCF8584 ISA adapter",
 };
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/dvb/bt8xx/dvb-bt8xx.c linux-2.6-6-rc3-mm2/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2004-05-09 11:05:31.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2004-05-09 17:38:16.000000000 +0200
@@ -261,6 +261,11 @@
 	.name            = "dvb_bt8xx",
         .id              = I2C_DRIVERID_DVB_BT878A,
 	.flags           = I2C_DF_NOTIFY,
+	/* ugly, but necessary: bt8x8 based budget dvb cards are handled by bttv on the
+	   lowest level and we fake a i2c client to get to know all bt8x8 based
+	   cards when they have been registered by bttv.
+	   we do a check for adap->id in order to find the right cards */
+	.class		 = I2C_CLASS_ALL,
         .attach_adapter  = dvb_bt8xx_attach,
         .detach_adapter  = dvb_bt8xx_detach,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/ir-kbd-i2c.c linux-2.6-6-rc3-mm2/drivers/media/video/ir-kbd-i2c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/ir-kbd-i2c.c	2004-05-09 11:05:31.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/ir-kbd-i2c.c	2004-05-09 17:39:18.000000000 +0200
@@ -247,6 +247,7 @@
         .name           = "ir remote kbd driver",
         .id             = I2C_DRIVERID_EXP3, /* FIXME */
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL;
         .attach_adapter = ir_probe,
         .detach_client  = ir_detach,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/zoran_card.c linux-2.6-6-rc3-mm2/drivers/media/video/zoran_card.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/zoran_card.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/zoran_card.c	2004-05-09 17:40:38.000000000 +0200
@@ -740,6 +740,7 @@
 	I2C_DEVNAME("zr36057"),
 	.id = I2C_HW_B_ZR36067,
 	.algo = NULL,
+	.class = I2C_CLASS_TV_ANALOG,
 	.client_register = zoran_i2c_client_register,
 	.client_unregister = zoran_i2c_client_unregister,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/video/aty/radeon_i2c.c linux-2.6-6-rc3-mm2/drivers/video/aty/radeon_i2c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/video/aty/radeon_i2c.c	2004-05-09 11:03:09.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/video/aty/radeon_i2c.c	2004-05-09 17:55:49.000000000 +0200
@@ -78,6 +78,7 @@
 	chan->adapter.id		= I2C_ALGO_ATI;
 	chan->adapter.algo_data		= &chan->algo;
 	chan->adapter.dev.parent	= &chan->rinfo->pdev->dev;
+	chan->adapter.class		= I2C_CLASS_NONE;
 	chan->algo.setsda		= radeon_gpio_setsda;
 	chan->algo.setscl		= radeon_gpio_setscl;
 	chan->algo.getsda		= radeon_gpio_getsda;
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/video/matrox/i2c-matroxfb.c linux-2.6-6-rc3-mm2/drivers/video/matrox/i2c-matroxfb.c
--- xx-linux-2.6-6-rc3-mm2/drivers/video/matrox/i2c-matroxfb.c	2004-05-09 11:03:09.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/video/matrox/i2c-matroxfb.c	2004-05-09 17:50:36.000000000 +0200
@@ -104,13 +104,14 @@
 };
 
 static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, 
-		unsigned int data, unsigned int clock, const char* name) {
+		unsigned int data, unsigned int clock, const char* name, unsigned int class) {
 	int err;
 
 	b->minfo = minfo;
 	b->mask.data = data;
 	b->mask.clock = clock;
 	b->adapter = matrox_i2c_adapter_template;
+	b->class = class;
 	snprintf(b->adapter.name, I2C_NAME_SIZE, name,
 		minfo->fbcon.node);
 	i2c_set_adapdata(&b->adapter, b);
@@ -160,22 +161,22 @@
 	switch (ACCESS_FBINFO(chip)) {
 		case MGA_2064:
 		case MGA_2164:
-			err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1B_DATA, DDC1B_CLK, "DDC:fb%u #0");
+			err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1B_DATA, DDC1B_CLK, "DDC:fb%u #0", I2C_CLASS_DDC);
 			break;
 		default:
-			err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1_DATA, DDC1_CLK, "DDC:fb%u #0");
+			err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1_DATA, DDC1_CLK, "DDC:fb%u #0", I2C_CLASS_DDC);
 			break;
 	}
 	if (err)
 		goto fail_ddc1;
 	if (ACCESS_FBINFO(devflags.dualhead)) {
-		err = i2c_bus_reg(&m2info->ddc2, minfo, DDC2_DATA, DDC2_CLK, "DDC:fb%u #1");
+		err = i2c_bus_reg(&m2info->ddc2, minfo, DDC2_DATA, DDC2_CLK, "DDC:fb%u #1", I2C_CLASS_DDC);
 		if (err == -ENODEV) {
 			printk(KERN_INFO "i2c-matroxfb: VGA->TV plug detected, DDC unavailable.\n");
 		} else if (err)
 			printk(KERN_INFO "i2c-matroxfb: Could not register secondary output i2c bus. Continuing anyway.\n");
 		/* Register maven bus even on G450/G550 */
-		err = i2c_bus_reg(&m2info->maven, minfo, MAT_DATA, MAT_CLK, "MAVEN:fb%u");
+		err = i2c_bus_reg(&m2info->maven, minfo, MAT_DATA, MAT_CLK, "MAVEN:fb%u", I2C_CLASS_TV_ANALOG);
 		if (err)
 			printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n");
 	}
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/video/matrox/matroxfb_maven.c linux-2.6-6-rc3-mm2/drivers/video/matrox/matroxfb_maven.c
--- xx-linux-2.6-6-rc3-mm2/drivers/video/matrox/matroxfb_maven.c	2004-05-09 11:03:09.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/video/matrox/matroxfb_maven.c	2004-05-09 17:46:07.000000000 +0200
@@ -1297,6 +1297,7 @@
 	.name		= "maven",
 	.id		= I2C_DRIVERID_MGATVO,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
 	.attach_adapter	= maven_attach_adapter,
 	.detach_client	= maven_detach_client,
 	.command	= maven_command,

[-- Attachment #7: 06-class-all.diff --]
[-- Type: text/plain, Size: 2545 bytes --]

diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ibm_iic.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ibm_iic.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ibm_iic.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ibm_iic.c	2004-05-09 18:19:44.000000000 +0200
@@ -607,6 +607,7 @@
 	i2c_set_adapdata(adap, dev);
 	adap->id = I2C_HW_OCP | iic_algo.id;
 	adap->algo = &iic_algo;
+	adap->class = I2C_CLASS_ALL;
 	adap->client_register = NULL;
 	adap->client_unregister = NULL;
 	adap->timeout = 1;
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-iop3xx.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-iop3xx.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-iop3xx.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-iop3xx.c	2004-05-09 18:17:57.000000000 +0200
@@ -507,18 +507,31 @@
 	.name			= ADAPTER_NAME_ROOT "0",
 	.id			= I2C_HW_IOP321,
 	.algo_data		= &algo_iop3xx_data0,
+	.class			= I2C_CLASS_ALL,
 };
 static struct i2c_adapter iop3xx_ops1 = {
 	.owner			= THIS_MODULE,
 	.name			= ADAPTER_NAME_ROOT "1",
 	.id			= I2C_HW_IOP321,
 	.algo_data		= &algo_iop3xx_data1,
+	.class			= I2C_CLASS_ALL,
 };
 
 static int __init i2c_iop3xx_init (void)
 {
-	return i2c_iop3xx_add_bus(&iop3xx_ops0) ||
-		i2c_iop3xx_add_bus(&iop3xx_ops1);
+	int ret;
+	
+	ret = i2c_iop3xx_add_bus(&iop3xx_ops0);
+	if (ret)
+		return ret;
+		
+	ret = i2c_iop3xx_add_bus(&iop3xx_ops1);
+	if (ret) {
+		i2c_iop3xx_del_bus(&iop3xx_ops0);
+		return ret;
+	}
+
+	return 0;
 }
 
 static void __exit i2c_iop3xx_exit (void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ite.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ite.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ite.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ite.c	2004-05-09 18:13:22.000000000 +0200
@@ -192,6 +192,7 @@
 	.owner		= THIS_MODULE,
 	.id		= I2C_HW_I_IIC,
 	.algo_data	= &iic_ite_data,
+	.class		= I2C_CLASS_ALL,
 	.dev		= {
 		.name	= "ITE IIC adapter",
 	},
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/scx200_i2c.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/scx200_i2c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/scx200_i2c.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/scx200_i2c.c	2004-05-09 18:13:55.000000000 +0200
@@ -84,6 +84,7 @@
 static struct i2c_adapter scx200_i2c_ops = {
 	.owner		   = THIS_MODULE,
 	.algo_data	   = &scx200_i2c_data,
+	.class		   = I2C_CLASS_ALL,
 	.name	= "NatSemi SCx200 I2C",
 };
 

[-- Attachment #8: 07-i2c-busses.diff --]
[-- Type: text/plain, Size: 4475 bytes --]

diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-frodo.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-frodo.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-frodo.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-frodo.c	2004-05-09 19:56:30.000000000 +0200
@@ -62,6 +62,7 @@
 	.owner			= THIS_MODULE,
 	.id			= I2C_HW_B_FRODO,
 	.algo_data		= &bit_frodo_data,
+	.class			= I2C_CLASS_ALL,
 	.dev			= {
 		.name		= "Frodo adapter driver",
 	},
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-hydra.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-hydra.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-hydra.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-hydra.c	2004-05-09 20:04:50.000000000 +0200
@@ -107,6 +107,7 @@
 	.owner		= THIS_MODULE,
 	.name		= "Hydra i2c",
 	.id		= I2C_HW_B_HYDRA,
+	.class		= I2C_CLASS_HWMON,
 	.algo_data	= &hydra_bit_data,
 };
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-i810.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-i810.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-i810.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-i810.c	2004-05-09 19:58:12.000000000 +0200
@@ -173,6 +173,7 @@
 static struct i2c_adapter i810_i2c_adapter = {
 	.owner		= THIS_MODULE,
 	.name		= "I810/I815 I2C Adapter",
+	.class		= I2C_CLASS_ALL, /* fixme, what's the correct class? */
 	.algo_data	= &i810_i2c_bit_data,
 };
 
@@ -189,6 +190,7 @@
 static struct i2c_adapter i810_ddc_adapter = {
 	.owner		= THIS_MODULE,
 	.name		= "I810/I815 DDC Adapter",
+	.class		= I2C_CLASS_DDC,
 	.algo_data	= &i810_ddc_bit_data,
 };
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ixp4xx.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ixp4xx.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ixp4xx.c	2004-05-09 11:06:43.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ixp4xx.c	2004-05-09 20:04:01.000000000 +0200
@@ -133,8 +133,9 @@
 	drv_data->algo_data.mdelay = 10;
 	drv_data->algo_data.timeout = 100;
 
-	drv_data->adapter.id = I2C_HW_B_IXP4XX,
-	drv_data->adapter.algo_data = &drv_data->algo_data,
+	drv_data->adapter.id = I2C_HW_B_IXP4XX;
+	drv_data->adapter.algo_data = &drv_data->algo_data;
+	drv_data->adapter.class = I2C_CLASS_ALL;
 
 	drv_data->adapter.dev.parent = &plat_dev->dev;
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-prosavage.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-prosavage.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-prosavage.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-prosavage.c	2004-05-09 20:00:12.000000000 +0200
@@ -181,12 +181,13 @@
 /*
  * adapter initialisation
  */
-static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
+static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg, unsigned int class)
 {
 	int ret;
 	p->adap.owner	  = THIS_MODULE;
 	p->adap.id	  = I2C_HW_B_S3VIA;
 	p->adap.algo_data = &p->algo;
+	p->adap.class	  = class;
 	p->adap.dev.parent = &dev->dev;
 	p->algo.setsda	  = bit_s3via_setsda;
 	p->algo.setscl	  = bit_s3via_setscl;
@@ -281,7 +282,7 @@
 	snprintf(bus->adap.name, sizeof(bus->adap.name),
 		"ProSavage I2C bus at %02x:%02x.%x",
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL1);
+	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL1, I2C_CLASS_ALL);
 	if (ret) {
 		goto err_adap;
 	}
@@ -292,7 +293,7 @@
 	snprintf(bus->adap.name, sizeof(bus->adap.name),
 		"ProSavage DDC bus at %02x:%02x.%x",
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL2);
+	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL2, I2C_CLASS_DDC);
 	if (ret) {
 		goto err_adap;
 	}
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-savage4.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-savage4.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-savage4.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-savage4.c	2004-05-09 20:01:31.000000000 +0200
@@ -149,6 +149,7 @@
 	.owner		= THIS_MODULE,
 	.name		= "I2C Savage4 adapter",
 	.algo_data	= &sav_i2c_bit_data,
+	.class		= I2C_CLASS_ALL, /* fixme: correct class entry? */
 };
 
 static struct pci_device_id savage4_ids[] __devinitdata = {

[-- Attachment #9: 08-i2c-core.diff --]
[-- Type: text/plain, Size: 1176 bytes --]

diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/i2c-core.c linux-2.6-6-rc3-mm2/drivers/i2c/i2c-core.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/i2c-core.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/i2c-core.c	2004-05-09 21:18:35.000000000 +0200
@@ -148,8 +148,11 @@
 	list_for_each(item,&drivers) {
 		driver = list_entry(item, struct i2c_driver, list);
 		if (driver->flags & I2C_DF_NOTIFY)
-			/* We ignore the return code; if it fails, too bad */
-			driver->attach_adapter(adap);
+			if (adap->class & driver->class)
+				/* We ignore the return code; if it fails, too bad */
+				driver->attach_adapter(adap);
+			else
+				printk("i2c-core: skipping driver '%s' on adapter '%s' (class mismatch)\n",driver->name, adap->name); 
 	}
 	up(&core_lists);
 
@@ -247,7 +250,10 @@
 	if (driver->flags & I2C_DF_NOTIFY) {
 		list_for_each(item,&adapters) {
 			adapter = list_entry(item, struct i2c_adapter, list);
-			driver->attach_adapter(adapter);
+			if (adapter->class & driver->class)
+				driver->attach_adapter(adapter);
+			else
+				printk("i2c-core: skipping driver '%s' on adapter '%s' (class mismatch)\n",driver->name, adap->name); 
 		}
 	}
 

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

* Re: Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter
  2005-05-19  6:25     ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add Michael Hunold
@ 2005-05-19  6:25       ` Jon Smirl
  -1 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2004-09-21 20:16 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Jean Delvare, sensors, Linux Kernel Mailing List, Greg KH

An addition to the class idea would be for clients to have priorities.
That would let me mark the bus as being for DDC. The highest priority
client would be the DDC driver. If the DDC driver can't find valid
EDID it could then fall back to letting the EEPROM driver try to find
the chip.

Something like this is important if we get a new EDID standard that
the DDC driver doesn't recognize. By letting the EEPROM driver load at
a lower priority you could still easily get to the ROM contents. Or
does it bother people if we let both EEPROM and DDC load on DDC class
buses?

-- 
Jon Smirl
jonsmirl@gmail.com

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

* Re: Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter
  2005-05-19  6:25     ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add Michael Hunold
@ 2005-05-19  6:25       ` Greg KH
  -1 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2004-09-24  0:02 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Jean Delvare, sensors, Linux Kernel Mailing List

On Tue, Sep 21, 2004 at 07:41:31PM +0200, Michael Hunold wrote:
> Please have a look and tell me what you think. The big problem will be, 
> that we cannot test all configurations, so it's possible that some 
> devices won't be recognized anymore, because the .class entries don't match.

I like the patches.  If you get them in a state you like (and drop the
printk(), and use dev_dbg() instead), and send them 1 patch per file
with the Signed-off-by: line, I'll be glad to apply them.

thanks,

greg k-h

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

* Re: Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter
  2005-05-19  6:25       ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Greg KH
@ 2005-05-19  6:25         ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-24  6:22 UTC (permalink / raw)
  To: Greg KH; +Cc: Jean Delvare, sensors, Linux Kernel Mailing List

Hi,

On 24.09.2004 02:02, Greg KH wrote:
> On Tue, Sep 21, 2004 at 07:41:31PM +0200, Michael Hunold wrote:
> 
>>Please have a look and tell me what you think. The big problem will be, 
>>that we cannot test all configurations, so it's possible that some 
>>devices won't be recognized anymore, because the .class entries don't match.

> I like the patches.  If you get them in a state you like (and drop the
> printk(), and use dev_dbg() instead), 

Ok.

> and send them 1 patch per file
> with the Signed-off-by: line, I'll be glad to apply them.

I'll re-create them against 2.6.9-rc2-mm2.

Do you really mean one patch per file, ie. about 50 separate patches? (I 
don't care, I simply write a script that splits them up)

> thanks,
> greg k-h

CU
Michael.


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

* Re: Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter
  2005-05-19  6:25         ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Michael Hunold
@ 2005-05-19  6:25           ` Greg KH
  -1 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2004-09-24 16:43 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Jean Delvare, sensors, Linux Kernel Mailing List

On Fri, Sep 24, 2004 at 08:22:34AM +0200, Michael Hunold wrote:
> Hi,
> 
> On 24.09.2004 02:02, Greg KH wrote:
> >On Tue, Sep 21, 2004 at 07:41:31PM +0200, Michael Hunold wrote:
> >
> >>Please have a look and tell me what you think. The big problem will be, 
> >>that we cannot test all configurations, so it's possible that some 
> >>devices won't be recognized anymore, because the .class entries don't 
> >>match.
> 
> >I like the patches.  If you get them in a state you like (and drop the
> >printk(), and use dev_dbg() instead), 
> 
> Ok.
> 
> >and send them 1 patch per file
> >with the Signed-off-by: line, I'll be glad to apply them.
> 
> I'll re-create them against 2.6.9-rc2-mm2.
> 
> Do you really mean one patch per file, ie. about 50 separate patches? (I 
> don't care, I simply write a script that splits them up)

Sorry, I ment one email per patch (you sent more than one patch in that
email.)

thanks,

greg k-h

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

* Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add
@ 2005-05-19  6:25     ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Jean Delvare; +Cc: sensors, Linux Kernel Mailing List, Greg KH

Hi,

On 21.09.2004 15:28, Jean Delvare wrote:
> On a completely different matter, what about the i2c subsystem class flags and
> checking mechanism? You had come with a first step some months ago (adding a
> class member to i2c clients), and your proposal (generalized check of i2c
> client class against adapter class) looked very good to me, but then we did
> not finish the job. What about it? 

I was unsure about the .class entries for some of the clients, then 
didn't find the time to investigate further and from then on the patches 
are bit-rotting on my harddisc. ;-(

> I am willing to help on the sensors front
> if you are going into this again someday. If I remember correctly, step 2 was
> about clearing manual class checks and filling all class members, and step 3
> was about implementing the generalized check in i2c-core. Am I right?

Yes, right. I've cleaned up the patches and attached them to this mail. 
Unfortunately, they only apply to 2.6.8(.1), but not 2.6.9-rc2-mm1. This 
is because SMBUS has been renamed to HWMON IIRC.

Please have a look and tell me what you think. The big problem will be, 
that we cannot test all configurations, so it's possible that some 
devices won't be recognized anymore, because the .class entries don't match.

Patches 1-3 are straight forward. For patches 4-7 I once created the 
following list:

=>4
#drivers/ieee1394/pcilynx.c => I2C_CLASS_NONE
#drivers/macintosh/therm_adt746x.c => I2C_CLASS_HWMON
#drivers/macintosh/therm_pm72.c => I2C_CLASS_HWMON
#drivers/macintosh/therm_windtunnel.c => I2C_CLASS_HWMON
#drivers/acorn/char/pcf8583.c => I2C_CLASS_ALL
#drivers/acorn/char/i2c.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-keywest.c: => I2C_CLASS_HWMON | I2C_CLASS_SOUND;
#sound/ppc/keywest.c => I2C_CLASS_SOUND
#sound/oss/dmasound/dac3550a.c => I2C_CLASS_SOUND
#sound/oss/dmasound/tas_common.c => I2C_CLASS_SOUND

=>5
#drivers/i2c/algos/i2c-algo-pcf.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-elektor.c => I2C_CLASS_ALL
#drivers/video/aty/radeon_i2c.c => I2C_CLASS_NONE
#drivers/video/matrox/i2c-matroxfb.c => I2C_CLASS_DDC and 
I2C_CLASS_TV_ANALOG
#drivers/video/matrox/matroxfb_maven.c => I2C_CLASS_TV_ANALOG
#drivers/media/video/zoran_card.c => I2C_CLASS_TV_ANALOG
#drivers/media/video/ir-kbd-i2c.c => I2C_CLASS_TV_ANALOG | 
I2C_CLASS_TV_DIGITAL
#drivers/media/dvb/bt8xx/dvb-bt8xx.c => I2C_CLASS_ALL

=>6
#drivers/i2c/busses/i2c-ibm_iic.c: => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-iop3xx.c:=> I2C_CLASS_ALL
#drivers/i2c/busses/scx200_i2c.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-ite.c => I2C_CLASS_ALL
(drivers/i2c/algos/i2c-algo-ite.c:)

=>7
#drivers/i2c/busses/i2c-frodo.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-i810.c => I2C_CLASS_ALL + I2C_CLASS_DDC
#drivers/i2c/busses/i2c-prosavage.c => I2C_CLASS_ALL + I2C_CLASS_DDC
#drivers/i2c/busses/i2c-savage4.c => I2C_CLASS_ALL
#drivers/i2c/busses/i2c-ixp4xx.c => I2C_CLASS_ALL, doesn't compile!?
#drivers/i2c/busses/i2c-hydra.c => I2C_CLASS_HWMON

> Thanks.

CU
Michael.

-------------- next part --------------
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/adv7170.c linux-2.6-6-rc3-mm2/drivers/media/video/adv7170.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/adv7170.c	2004-05-09 11:03:04.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/adv7170.c	2004-05-09 11:28:12.000000000 +0200
@@ -516,6 +516,7 @@
 
 	.id = I2C_DRIVERID_ADV7170,
 	.flags = I2C_DF_NOTIFY,
+ 	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = adv7170_attach_adapter,
 	.detach_client = adv7170_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/adv7175.c linux-2.6-6-rc3-mm2/drivers/media/video/adv7175.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/adv7175.c	2004-05-09 11:03:04.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/adv7175.c	2004-05-09 11:27:55.000000000 +0200
@@ -538,6 +538,7 @@
 
 	.id = I2C_DRIVERID_ADV7175,
 	.flags = I2C_DF_NOTIFY,
+ 	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = adv7175_attach_adapter,
 	.detach_client = adv7175_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt819.c linux-2.6-6-rc3-mm2/drivers/media/video/bt819.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt819.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/bt819.c	2004-05-09 11:24:22.000000000 +0200
@@ -642,6 +642,7 @@
 
 	.id = I2C_DRIVERID_BT819,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = bt819_attach_adapter,
 	.detach_client = bt819_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt856.c linux-2.6-6-rc3-mm2/drivers/media/video/bt856.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt856.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/bt856.c	2004-05-09 11:23:22.000000000 +0200
@@ -423,6 +423,7 @@
 
 	.id = I2C_DRIVERID_BT856,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = bt856_attach_adapter,
 	.detach_client = bt856_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7110.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7110.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7110.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7110.c	2004-05-09 11:22:57.000000000 +0200
@@ -599,6 +599,7 @@
 
 	.id = I2C_DRIVERID_SAA7110,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = saa7110_attach_adapter,
 	.detach_client = saa7110_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7111.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7111.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7111.c	2004-05-09 11:06:43.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7111.c	2004-05-09 11:24:54.000000000 +0200
@@ -608,7 +608,8 @@
 
 	.id = I2C_DRIVERID_SAA7111A,
 	.flags = I2C_DF_NOTIFY,
-
+	.class = I2C_CLASS_TV_ANALOG,
+	
 	.attach_adapter = saa7111_attach_adapter,
 	.detach_client = saa7111_detach_client,
 	.command = saa7111_command,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7114.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7114.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7114.c	2004-05-09 11:03:04.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7114.c	2004-05-09 11:27:15.000000000 +0200
@@ -1222,6 +1222,7 @@
 
 	.id = I2C_DRIVERID_SAA7114,
 	.flags = I2C_DF_NOTIFY,
+ 	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = saa7114_attach_adapter,
 	.detach_client = saa7114_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7185.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7185.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7185.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7185.c	2004-05-09 11:23:55.000000000 +0200
@@ -505,6 +505,7 @@
 
 	.id = I2C_DRIVERID_SAA7185B,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = saa7185_attach_adapter,
 	.detach_client = saa7185_detach_client,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9840.c linux-2.6-6-rc3-mm2/drivers/media/video/tda9840.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9840.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tda9840.c	2004-05-09 11:26:35.000000000 +0200
@@ -263,6 +263,7 @@
 	.name		= "tda9840 driver",
 	.id		= I2C_DRIVERID_TDA9840,
 	.flags		= I2C_DF_NOTIFY,
+ 	.class 		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = tda9840_attach,
         .detach_client	= tda9840_detach,
         .command	= tda9840_command,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tea6415c.c linux-2.6-6-rc3-mm2/drivers/media/video/tea6415c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tea6415c.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tea6415c.c	2004-05-09 11:26:52.000000000 +0200
@@ -212,6 +212,7 @@
 	.name		= "tea6415c driver",
 	.id		= I2C_DRIVERID_TEA6415C,
 	.flags		= I2C_DF_NOTIFY,
+ 	.class 		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = tea6415c_attach,
         .detach_client	= tea6415c_detach,
         .command	= tea6415c_command,
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tea6420.c linux-2.6-6-rc3-mm2/drivers/media/video/tea6420.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tea6420.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tea6420.c	2004-05-09 11:26:09.000000000 +0200
@@ -192,8 +192,9 @@
 	.name		= "tea6420 driver",
 	.id		= I2C_DRIVERID_TEA6420,
 	.flags		= I2C_DF_NOTIFY,
-        .attach_adapter = tea6420_attach,
+ 	.class 		= I2C_CLASS_TV_ANALOG,
+	.attach_adapter = tea6420_attach,
         .detach_client	= tea6420_detach,
         .command	= tea6420_command,
 };
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tuner-3036.c linux-2.6-6-rc3-mm2/drivers/media/video/tuner-3036.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tuner-3036.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tuner-3036.c	2004-05-09 11:25:25.000000000 +0200
@@ -185,6 +185,7 @@
 	.name		=	"sab3036",
 	.id		=	I2C_DRIVERID_SAB3036,
         .flags		=	I2C_DF_NOTIFY,
+	.class 		=	I2C_CLASS_TV_ANALOG,
 	.attach_adapter =	tuner_probe,
 	.detach_client  =	tuner_detach,
 	.command	=	tuner_command
@@ -200,8 +201,7 @@
 int __init
 tuner3036_init(void)
 {
-	i2c_add_driver(&i2c_driver_tuner);
-	return 0;
+	return i2c_add_driver(&i2c_driver_tuner);
 }
 
 void __exit
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/vpx3220.c linux-2.6-6-rc3-mm2/drivers/media/video/vpx3220.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/vpx3220.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/vpx3220.c	2004-05-09 11:27:33.000000000 +0200
@@ -731,6 +731,7 @@
 
 	.id = I2C_DRIVERID_VPX3220,
 	.flags = I2C_DF_NOTIFY,
+ 	.class = I2C_CLASS_TV_ANALOG,
 
 	.attach_adapter = vpx3220_attach_adapter,
 	.detach_client = vpx3220_detach_client,
-------------- next part --------------
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt832.c linux-2.6-6-rc3-mm2/drivers/media/video/bt832.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/bt832.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/bt832.c	2004-05-09 14:49:58.000000000 +0200
@@ -197,9 +197,7 @@
 
 static int bt832_probe(struct i2c_adapter *adap)
 {
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, bt832_attach);
-	return 0;
+	return i2c_probe(adap, &addr_data, bt832_attach);
 }
 
 static int bt832_detach(struct i2c_client *client)
@@ -243,6 +241,7 @@
         .name           = "i2c bt832 driver",
         .id             = -1, /* FIXME */
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = bt832_probe,
         .detach_client  = bt832_detach,
         .command        = bt832_command,
@@ -257,8 +256,7 @@
 
 int bt832_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void bt832_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/msp3400.c linux-2.6-6-rc3-mm2/drivers/media/video/msp3400.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/msp3400.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/msp3400.c	2004-05-09 14:48:30.000000000 +0200
@@ -1222,6 +1222,7 @@
         .name           = "i2c msp3400 driver",
         .id             = I2C_DRIVERID_MSP3400,
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = msp_probe,
         .detach_client  = msp_detach,
         .command        = msp_command,
@@ -1353,19 +1354,7 @@
 
 static int msp_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, msp_attach);
-#else
-	switch (adap->id) {
-	case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	//case I2C_ALGO_SAA7134:
-		return i2c_probe(adap, &addr_data, msp_attach);
-		break;
-	}
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, msp_attach);
 }
 
 static void msp_wake_thread(struct i2c_client *client)
@@ -1558,8 +1547,7 @@
 
 static int msp3400_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void msp3400_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa5246a.c linux-2.6-6-rc3-mm2/drivers/media/video/saa5246a.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa5246a.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa5246a.c	2004-05-09 14:52:53.000000000 +0200
@@ -143,9 +143,7 @@
  */
 static int saa5246a_probe(struct i2c_adapter *adap)
 {
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, saa5246a_attach);
-	return 0;
+	return i2c_probe(adap, &addr_data, saa5246a_attach);
 }
 
 static int saa5246a_detach(struct i2c_client *client)
@@ -174,6 +172,7 @@
 	.name 		= IF_NAME,		/* name */
 	.id 		= I2C_DRIVERID_SAA5249, /* in i2c.h */
 	.flags 		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
 	.attach_adapter = saa5246a_probe,
 	.detach_client  = saa5246a_detach,
 	.command 	= saa5246a_command
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa5249.c linux-2.6-6-rc3-mm2/drivers/media/video/saa5249.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa5249.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa5249.c	2004-05-09 14:50:30.000000000 +0200
@@ -219,9 +219,7 @@
  
 static int saa5249_probe(struct i2c_adapter *adap)
 {
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, saa5249_attach);
-	return 0;
+	return i2c_probe(adap, &addr_data, saa5249_attach);
 }
 
 static int saa5249_detach(struct i2c_client *client)
@@ -249,6 +247,7 @@
 	.name 		= IF_NAME,		/* name */
 	.id 		= I2C_DRIVERID_SAA5249, /* in i2c.h */
 	.flags 		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
 	.attach_adapter = saa5249_probe,
 	.detach_client  = saa5249_detach,
 	.command 	= saa5249_command
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7134/saa6752hs.c linux-2.6-6-rc3-mm2/drivers/media/video/saa7134/saa6752hs.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/saa7134/saa6752hs.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/saa7134/saa6752hs.c	2004-05-09 14:47:01.000000000 +0200
@@ -335,9 +335,7 @@
 
 static int saa6752hs_probe(struct i2c_adapter *adap)
 {
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, saa6752hs_attach);
-	return 0;
+	return i2c_probe(adap, &addr_data, saa6752hs_attach);
 }
 
 static int saa6752hs_detach(struct i2c_client *client)
@@ -376,6 +373,7 @@
         .name           = "i2c saa6752hs MPEG encoder",
         .id             = I2C_DRIVERID_SAA6752HS,
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = saa6752hs_probe,
         .detach_client  = saa6752hs_detach,
         .command        = saa6752hs_command,
@@ -390,8 +388,7 @@
 
 static int saa6752hs_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void saa6752hs_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda7432.c linux-2.6-6-rc3-mm2/drivers/media/video/tda7432.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda7432.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tda7432.c	2004-05-09 14:49:17.000000000 +0200
@@ -338,14 +338,7 @@
 
 static int tda7432_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, tda7432_attach);
-#else
-	if (adap->id = (I2C_ALGO_BIT | I2C_HW_B_BT848))
-		return i2c_probe(adap, &addr_data, tda7432_attach);
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, tda7432_attach);
 }
 
 static int tda7432_detach(struct i2c_client *client)
@@ -520,6 +513,7 @@
         .name            = "i2c tda7432 driver",
 	.id              = I2C_DRIVERID_TDA7432,
         .flags           = I2C_DF_NOTIFY,
+	.class		 = I2C_CLASS_TV_ANALOG,
 	.attach_adapter  = tda7432_probe,
         .detach_client   = tda7432_detach,
         .command         = tda7432_command,
@@ -538,8 +532,7 @@
 		printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n");
 		return -EINVAL;
 	}
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tda7432_fini(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9875.c linux-2.6-6-rc3-mm2/drivers/media/video/tda9875.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9875.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tda9875.c	2004-05-09 14:48:00.000000000 +0200
@@ -272,14 +272,7 @@
 
 static int tda9875_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, tda9875_attach);
-#else
-	if (adap->id = (I2C_ALGO_BIT | I2C_HW_B_BT848))
-		return i2c_probe(adap, &addr_data, tda9875_attach);
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, tda9875_attach);
 }
 
 static int tda9875_detach(struct i2c_client *client)
@@ -391,6 +384,7 @@
         .name           = "i2c tda9875 driver",
         .id             = I2C_DRIVERID_TDA9875,
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
 	.attach_adapter = tda9875_probe,
         .detach_client  = tda9875_detach,
         .command        = tda9875_command,
@@ -405,8 +399,7 @@
 
 static int tda9875_init(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tda9875_fini(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9887.c linux-2.6-6-rc3-mm2/drivers/media/video/tda9887.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tda9887.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tda9887.c	2004-05-09 14:46:31.000000000 +0200
@@ -370,19 +370,7 @@
 
 static int tda9887_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, tda9887_attach);
-#else
-	switch (adap->id) {
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
-	case I2C_ALGO_SAA7134:
-		return i2c_probe(adap, &addr_data, tda9887_attach);
-		break;
-	}
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, tda9887_attach);
 }
 
 static int tda9887_detach(struct i2c_client *client)
@@ -447,6 +435,7 @@
         .name           = "i2c tda9887 driver",
         .id             = -1, /* FIXME */
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = tda9887_probe,
         .detach_client  = tda9887_detach,
         .command        = tda9887_command,
@@ -460,8 +449,7 @@
 
 static int tda9887_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tda9887_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tuner.c linux-2.6-6-rc3-mm2/drivers/media/video/tuner.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tuner.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tuner.c	2004-05-09 14:51:10.000000000 +0200
@@ -1067,21 +1067,7 @@
 	}
 	this_adap = 0;
 
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, tuner_attach);
-#else
-	switch (adap->id) {
-	case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
-	case I2C_ALGO_SAA7134:
-	case I2C_ALGO_SAA7146:
-		return i2c_probe(adap, &addr_data, tuner_attach);
-		break;
-	}
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, tuner_attach);
 }
 
 static int tuner_detach(struct i2c_client *client)
@@ -1184,6 +1170,7 @@
         .name           = "i2c TV tuner driver",
         .id             = I2C_DRIVERID_TUNER,
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
         .attach_adapter = tuner_probe,
         .detach_client  = tuner_detach,
         .command        = tuner_command,
@@ -1197,8 +1184,7 @@
 
 static int tuner_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tuner_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tvaudio.c linux-2.6-6-rc3-mm2/drivers/media/video/tvaudio.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tvaudio.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tvaudio.c	2004-05-09 14:47:38.000000000 +0200
@@ -1497,18 +1497,7 @@
 
 static int chip_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, chip_attach);
-#else
-	switch (adap->id) {
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
-	case I2C_ALGO_SAA7134:
-		return i2c_probe(adap, &addr_data, chip_attach);
-	}
-#endif
-	return 0;
+	return i2c_probe(adap, &addr_data, chip_attach);
 }
 
 static int chip_detach(struct i2c_client *client)
@@ -1639,6 +1628,7 @@
         .name            = "generic i2c audio driver",
         .id              = I2C_DRIVERID_TVAUDIO,
         .flags           = I2C_DF_NOTIFY,
+	.class		 = I2C_CLASS_TV_ANALOG,
         .attach_adapter  = chip_probe,
         .detach_client   = chip_detach,
         .command         = chip_command,
@@ -1659,8 +1649,7 @@
 	for (desc = chiplist; desc->name != NULL; desc++)
 		printk("%s%s", (desc = chiplist) ? "" : ",",desc->name);
 	printk("\n");
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void audiochip_cleanup_module(void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/tvmixer.c linux-2.6-6-rc3-mm2/drivers/media/video/tvmixer.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/tvmixer.c	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/tvmixer.c	2004-05-09 14:52:10.000000000 +0200
@@ -232,6 +232,7 @@
 	.flags           = I2C_DF_NOTIFY,
         .detach_adapter  = tvmixer_adapters,
 #endif
+	.class		 = I2C_CLASS_TV_ANALOG,
         .attach_adapter  = tvmixer_adapters,
         .detach_client   = tvmixer_clients,
 };
@@ -263,23 +264,6 @@
 	struct video_audio va;
 	int i,minor;
 
-#ifdef I2C_CLASS_TV_ANALOG
-	if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
-		return -1;
-#else
-	/* TV card ??? */
-	switch (client->adapter->id) {
-	case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
-	case I2C_ALGO_BIT | I2C_HW_B_BT848:
-	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
-		/* ok, have a look ... */
-		break;
-	default:
-		/* ignore that one */
-		return -1;
-	}
-#endif
-
 	/* unregister ?? */
 	for (i = 0; i < DEV_MAX; i++) {
 		if (devices[i].dev = client) {
@@ -334,8 +318,7 @@
 	
 	for (i = 0; i < DEV_MAX; i++)
 		devices[i].minor = -1;
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
 static void tvmixer_cleanup_module(void)
-------------- next part --------------
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/adm1021.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/adm1021.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/adm1021.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/adm1021.c	2004-05-09 16:17:00.000000000 +0200
@@ -144,6 +144,7 @@
 	.name		= "adm1021",
 	.id		= I2C_DRIVERID_ADM1021,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= adm1021_attach_adapter,
 	.detach_client	= adm1021_detach_client,
 };
@@ -200,8 +201,6 @@
 
 static int adm1021_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, adm1021_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/asb100.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/asb100.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/asb100.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/asb100.c	2004-05-09 16:13:42.000000000 +0200
@@ -233,6 +233,7 @@
 	.name		= "asb100",
 	.id		= I2C_DRIVERID_ASB100,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= asb100_attach_adapter,
 	.detach_client	= asb100_detach_client,
 };
@@ -609,8 +610,6 @@
  */
 static int asb100_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, asb100_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/ds1621.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/ds1621.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/ds1621.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/ds1621.c	2004-05-09 16:11:42.000000000 +0200
@@ -92,6 +92,7 @@
 	.name		= "ds1621",
 	.id		= I2C_DRIVERID_DS1621,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= ds1621_attach_adapter,
 	.detach_client	= ds1621_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/eeprom.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/eeprom.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/eeprom.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/eeprom.c	2004-05-09 16:11:59.000000000 +0200
@@ -82,6 +82,7 @@
 	.name		= "eeprom",
 	.id		= I2C_DRIVERID_EEPROM,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= eeprom_attach_adapter,
 	.detach_client	= eeprom_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/fscher.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/fscher.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/fscher.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/fscher.c	2004-05-09 16:13:00.000000000 +0200
@@ -124,6 +124,7 @@
 	.name		= "fscher",
 	.id		= I2C_DRIVERID_FSCHER,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= fscher_attach_adapter,
 	.detach_client	= fscher_detach_client,
 };
@@ -293,8 +294,6 @@
 
 static int fscher_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, fscher_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/gl518sm.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/gl518sm.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/gl518sm.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/gl518sm.c	2004-05-09 16:12:21.000000000 +0200
@@ -156,6 +156,7 @@
 	.name		= "gl518sm",
 	.id		= I2C_DRIVERID_GL518,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= gl518_attach_adapter,
 	.detach_client	= gl518_detach_client,
 };
@@ -335,8 +336,6 @@
 
 static int gl518_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, gl518_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/it87.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/it87.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/it87.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/it87.c	2004-05-09 16:16:14.000000000 +0200
@@ -173,6 +173,7 @@
 	.name		= "it87",
 	.id		= I2C_DRIVERID_IT87,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= it87_attach_adapter,
 	.detach_client	= it87_detach_client,
 };
@@ -500,8 +501,6 @@
      * when a new adapter is inserted (and it87_driver is still present) */
 static int it87_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, it87_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm78.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm78.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm78.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm78.c	2004-05-09 16:15:57.000000000 +0200
@@ -229,6 +229,7 @@
 	.name		= "lm78",
 	.id		= I2C_DRIVERID_LM78,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= lm78_attach_adapter,
 	.detach_client	= lm78_detach_client,
 };
@@ -488,8 +489,6 @@
      * when a new adapter is inserted (and lm78_driver is still present) */
 static int lm78_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, lm78_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm80.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm80.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm80.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm80.c	2004-05-09 16:15:28.000000000 +0200
@@ -156,6 +156,7 @@
 	.name		= "lm80",
 	.id		= I2C_DRIVERID_LM80,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= lm80_attach_adapter,
 	.detach_client	= lm80_detach_client,
 };
@@ -376,8 +377,6 @@
 
 static int lm80_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, lm80_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm83.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm83.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm83.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm83.c	2004-05-09 16:15:08.000000000 +0200
@@ -125,6 +125,7 @@
 	.name		= "lm83",
 	.id		= I2C_DRIVERID_LM83,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= lm83_attach_adapter,
 	.detach_client	= lm83_detach_client,
 };
@@ -216,8 +217,6 @@
 
 static int lm83_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, lm83_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm85.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm85.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm85.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm85.c	2004-05-09 16:14:53.000000000 +0200
@@ -403,6 +403,7 @@
 	.name           = "lm85",
 	.id             = I2C_DRIVERID_LM85,
 	.flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter = lm85_attach_adapter,
 	.detach_client  = lm85_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm90.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm90.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm90.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/lm90.c	2004-05-09 16:14:33.000000000 +0200
@@ -146,6 +146,7 @@
 	.name		= "lm90",
 	.id		= I2C_DRIVERID_LM90,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= lm90_attach_adapter,
 	.detach_client	= lm90_detach_client,
 };
@@ -274,8 +275,6 @@
 
 static int lm90_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, lm90_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8574.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8574.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8574.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8574.c	2004-05-09 16:10:36.000000000 +0200
@@ -73,6 +73,7 @@
 	.name		= "pcf8574",
 	.id		= I2C_DRIVERID_PCF8574,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= pcf8574_attach_adapter,
 	.detach_client	= pcf8574_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8591.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8591.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8591.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/pcf8591.c	2004-05-09 16:10:09.000000000 +0200
@@ -95,6 +95,7 @@
 	.name		= "pcf8591",
 	.id		= I2C_DRIVERID_PCF8591,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= pcf8591_attach_adapter,
 	.detach_client	= pcf8591_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/via686a.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/via686a.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/via686a.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/via686a.c	2004-05-09 16:16:46.000000000 +0200
@@ -586,6 +586,7 @@
 	.name		= "via686a",
 	.id		= I2C_DRIVERID_VIA686A,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= via686a_attach_adapter,
 	.detach_client	= via686a_detach_client,
 };
@@ -594,8 +595,6 @@
 /* This is called when the module is loaded */
 static int via686a_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, via686a_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83627hf.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83627hf.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83627hf.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83627hf.c	2004-05-09 16:11:27.000000000 +0200
@@ -331,6 +331,7 @@
 	.name		= "w83627hf",
 	.id		= I2C_DRIVERID_W83627HF,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= w83627hf_attach_adapter,
 	.detach_client	= w83627hf_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83781d.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83781d.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83781d.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83781d.c	2004-05-09 16:17:18.000000000 +0200
@@ -281,6 +281,7 @@
 	.name = "w83781d",
 	.id = I2C_DRIVERID_W83781D,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_HWMON,
 	.attach_adapter = w83781d_attach_adapter,
 	.detach_client = w83781d_detach_client,
 };
@@ -905,8 +906,6 @@
 static int
 w83781d_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, w83781d_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83l785ts.c linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83l785ts.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83l785ts.c	2004-05-09 11:11:10.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/chips/w83l785ts.c	2004-05-09 16:13:22.000000000 +0200
@@ -96,6 +96,7 @@
 	.name		= "w83l785ts",
 	.id		= I2C_DRIVERID_W83L785TS,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= w83l785ts_attach_adapter,
 	.detach_client	= w83l785ts_detach_client,
 };
@@ -145,8 +146,6 @@
 
 static int w83l785ts_attach_adapter(struct i2c_adapter *adapter)
 {
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
 	return i2c_detect(adapter, &addr_data, w83l785ts_detect);
 }
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/i2c-dev.c linux-2.6-6-rc3-mm2/drivers/i2c/i2c-dev.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/i2c-dev.c	2004-05-09 11:05:29.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/i2c-dev.c	2004-05-09 16:06:33.000000000 +0200
@@ -500,6 +500,7 @@
 	.name		= "dev_driver",
 	.id		= I2C_DRIVERID_I2CDEV,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_ALL,
 	.attach_adapter	= i2cdev_attach_adapter,
 	.detach_adapter	= i2cdev_detach_adapter,
 	.detach_client	= i2cdev_detach_client,
-------------- next part --------------
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/acorn/char/i2c.c linux-2.6-6-rc3-mm2/drivers/acorn/char/i2c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/acorn/char/i2c.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/acorn/char/i2c.c	2004-05-09 16:31:58.000000000 +0200
@@ -345,6 +345,7 @@
 static struct i2c_adapter ioc_ops = {
 	.id			= I2C_HW_B_IOC,
 	.algo_data		= &ioc_data,
+	.class			= I2C_CLASS_ALL,
 	.client_register	= ioc_client_reg,
 	.client_unregister	= ioc_client_unreg,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/acorn/char/pcf8583.c linux-2.6-6-rc3-mm2/drivers/acorn/char/pcf8583.c
--- xx-linux-2.6-6-rc3-mm2/drivers/acorn/char/pcf8583.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/acorn/char/pcf8583.c	2004-05-09 16:33:20.000000000 +0200
@@ -227,6 +227,7 @@
 	.name		= "PCF8583",
 	.id		= I2C_DRIVERID_PCF8583,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_ALL, /* fixme: add another I2C_CLASS_xxx entry for Acorn? */
 	.attach_adapter	= pcf8583_probe,
 	.detach_client	= pcf8583_detach,
 	.command	= pcf8583_command
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-keywest.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-keywest.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-keywest.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-keywest.c	2004-05-09 16:37:41.000000000 +0200
@@ -619,6 +619,7 @@
 		chan->iface = iface;
 		chan->chan_no = i;
 		chan->adapter.id = I2C_ALGO_SMBUS;
+		chan->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SOUND;
 		chan->adapter.algo = &keywest_algorithm;
 		chan->adapter.algo_data = NULL;
 		chan->adapter.client_register = NULL;
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/ieee1394/pcilynx.c linux-2.6-6-rc3-mm2/drivers/ieee1394/pcilynx.c
--- xx-linux-2.6-6-rc3-mm2/drivers/ieee1394/pcilynx.c	2004-05-09 11:05:30.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/ieee1394/pcilynx.c	2004-05-09 16:42:30.000000000 +0200
@@ -1799,6 +1799,7 @@
                 i2c_adapter = bit_ops;
                 i2c_adapter_data = bit_data;
                 i2c_adapter.algo_data = &i2c_adapter_data;
+		i2c_adapter.class = I2C_CLASS_NONE;
                 i2c_adapter_data.data = lynx;
 
 		PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d",
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_adt746x.c linux-2.6-6-rc3-mm2/drivers/macintosh/therm_adt746x.c
--- xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_adt746x.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/macintosh/therm_adt746x.c	2004-05-09 16:30:02.000000000 +0200
@@ -164,6 +164,7 @@
 	.name		="Apple Thermostat ADT746x",
 	.id		=0xDEAD7467,
 	.flags		=I2C_DF_NOTIFY,
+	.class		=I2C_CLASS_HWMON,
 	.attach_adapter	=&attach_thermostat,
 	.detach_adapter	=&detach_thermostat,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_pm72.c linux-2.6-6-rc3-mm2/drivers/macintosh/therm_pm72.c
--- xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_pm72.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/macintosh/therm_pm72.c	2004-05-09 16:29:32.000000000 +0200
@@ -142,6 +142,7 @@
 	.name		= "therm_pm72",
 	.id		= 0xDEADBEEF,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter	= therm_pm72_attach,
 	.detach_adapter	= therm_pm72_detach,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_windtunnel.c linux-2.6-6-rc3-mm2/drivers/macintosh/therm_windtunnel.c
--- xx-linux-2.6-6-rc3-mm2/drivers/macintosh/therm_windtunnel.c	2004-05-09 11:03:40.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/macintosh/therm_windtunnel.c	2004-05-09 16:29:13.000000000 +0200
@@ -357,6 +357,7 @@
 	.name		= "Apple G4 Thermostat/Fan",
 	.id		= I2C_DRIVERID_G4FAN,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_HWMON,
 	.attach_adapter = &do_attach,
 	.detach_client	= &do_detach,
 	.command	= NULL,
diff -ura xx-linux-2.6-6-rc3-mm2/include/linux/i2c.h linux-2.6-6-rc3-mm2/include/linux/i2c.h
--- xx-linux-2.6-6-rc3-mm2/include/linux/i2c.h	2004-05-09 11:11:11.000000000 +0200
+++ linux-2.6-6-rc3-mm2/include/linux/i2c.h	2004-05-09 16:42:13.000000000 +0200
@@ -285,7 +285,8 @@
 #define I2C_CLIENT_TEN	0x10			/* we have a ten bit chip address	*/
 						/* Must equal I2C_M_TEN below */
 
-/* i2c adapter classes (bitmask) */
+/* i2c classes (bitmask) */
+#define I2C_CLASS_NONE		0	/* none, don't use */
 #define I2C_CLASS_HWMON		(1<<0)	/* lm_sensors, ... */
 #define I2C_CLASS_TV_ANALOG	(1<<1)	/* bttv + friends */
 #define I2C_CLASS_TV_DIGITAL	(1<<2)	/* dvb cards */
diff -ura xx-linux-2.6-6-rc3-mm2/sound/oss/dmasound/dac3550a.c linux-2.6-6-rc3-mm2/sound/oss/dmasound/dac3550a.c
--- xx-linux-2.6-6-rc3-mm2/sound/oss/dmasound/dac3550a.c	2004-05-09 11:04:50.000000000 +0200
+++ linux-2.6-6-rc3-mm2/sound/oss/dmasound/dac3550a.c	2004-05-09 16:38:47.000000000 +0200
@@ -47,6 +47,7 @@
 	.name			= "DAC3550A driver  V " DACA_VERSION,
 	.id			= I2C_DRIVERID_DACA,
 	.flags			= I2C_DF_NOTIFY,
+	.class			= I2C_CLASS_SOUND,
 	.attach_adapter		= daca_attach_adapter,
 	.detach_client		= daca_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/sound/oss/dmasound/tas_common.c linux-2.6-6-rc3-mm2/sound/oss/dmasound/tas_common.c
--- xx-linux-2.6-6-rc3-mm2/sound/oss/dmasound/tas_common.c	2004-05-09 11:04:50.000000000 +0200
+++ linux-2.6-6-rc3-mm2/sound/oss/dmasound/tas_common.c	2004-05-09 16:39:01.000000000 +0200
@@ -50,6 +50,7 @@
 	.owner		= THIS_MODULE,
 	.name		= "tas",
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_SOUND,
 	.attach_adapter	= tas_attach_adapter,
 	.detach_client	= tas_detach_client,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/sound/ppc/keywest.c linux-2.6-6-rc3-mm2/sound/ppc/keywest.c
--- xx-linux-2.6-6-rc3-mm2/sound/ppc/keywest.c	2004-05-09 11:06:53.000000000 +0200
+++ linux-2.6-6-rc3-mm2/sound/ppc/keywest.c	2004-05-09 16:38:03.000000000 +0200
@@ -44,6 +44,7 @@
 	.name = "PMac Keywest Audio",
 	.id = I2C_DRIVERID_KEYWEST,
 	.flags = I2C_DF_NOTIFY,
+	.class = I2C_CLASS_SOUND,
 	.attach_adapter = &keywest_attach_adapter,
 	.detach_client = &keywest_detach_client,
 };
-------------- next part --------------
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/algos/i2c-algo-pcf.c linux-2.6-6-rc3-mm2/drivers/i2c/algos/i2c-algo-pcf.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/algos/i2c-algo-pcf.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/algos/i2c-algo-pcf.c	2004-05-09 18:00:47.000000000 +0200
@@ -449,7 +449,8 @@
 
 	adap->id |= pcf_algo.id;
 	adap->algo = &pcf_algo;
-
+	adap->class = I2C_CLASS_ALL;
+	
 	adap->timeout = 100;		/* default values, should	*/
 	adap->retries = 3;		/* be replaced by defines	*/
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-elektor.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-elektor.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-elektor.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-elektor.c	2004-05-09 17:57:16.000000000 +0200
@@ -171,6 +171,7 @@
 	.owner		= THIS_MODULE,
 	.id		= I2C_HW_P_ELEK,
 	.algo_data	= &pcf_isa_data,
+	.class		= I2C_CLASS_ALL,
 	.name		= "PCF8584 ISA adapter",
 };
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/dvb/bt8xx/dvb-bt8xx.c linux-2.6-6-rc3-mm2/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2004-05-09 11:05:31.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2004-05-09 17:38:16.000000000 +0200
@@ -261,6 +261,11 @@
 	.name            = "dvb_bt8xx",
         .id              = I2C_DRIVERID_DVB_BT878A,
 	.flags           = I2C_DF_NOTIFY,
+	/* ugly, but necessary: bt8x8 based budget dvb cards are handled by bttv on the
+	   lowest level and we fake a i2c client to get to know all bt8x8 based
+	   cards when they have been registered by bttv.
+	   we do a check for adap->id in order to find the right cards */
+	.class		 = I2C_CLASS_ALL,
         .attach_adapter  = dvb_bt8xx_attach,
         .detach_adapter  = dvb_bt8xx_detach,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/ir-kbd-i2c.c linux-2.6-6-rc3-mm2/drivers/media/video/ir-kbd-i2c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/ir-kbd-i2c.c	2004-05-09 11:05:31.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/ir-kbd-i2c.c	2004-05-09 17:39:18.000000000 +0200
@@ -247,6 +247,7 @@
         .name           = "ir remote kbd driver",
         .id             = I2C_DRIVERID_EXP3, /* FIXME */
         .flags          = I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL;
         .attach_adapter = ir_probe,
         .detach_client  = ir_detach,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/media/video/zoran_card.c linux-2.6-6-rc3-mm2/drivers/media/video/zoran_card.c
--- xx-linux-2.6-6-rc3-mm2/drivers/media/video/zoran_card.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/media/video/zoran_card.c	2004-05-09 17:40:38.000000000 +0200
@@ -740,6 +740,7 @@
 	I2C_DEVNAME("zr36057"),
 	.id = I2C_HW_B_ZR36067,
 	.algo = NULL,
+	.class = I2C_CLASS_TV_ANALOG,
 	.client_register = zoran_i2c_client_register,
 	.client_unregister = zoran_i2c_client_unregister,
 };
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/video/aty/radeon_i2c.c linux-2.6-6-rc3-mm2/drivers/video/aty/radeon_i2c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/video/aty/radeon_i2c.c	2004-05-09 11:03:09.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/video/aty/radeon_i2c.c	2004-05-09 17:55:49.000000000 +0200
@@ -78,6 +78,7 @@
 	chan->adapter.id		= I2C_ALGO_ATI;
 	chan->adapter.algo_data		= &chan->algo;
 	chan->adapter.dev.parent	= &chan->rinfo->pdev->dev;
+	chan->adapter.class		= I2C_CLASS_NONE;
 	chan->algo.setsda		= radeon_gpio_setsda;
 	chan->algo.setscl		= radeon_gpio_setscl;
 	chan->algo.getsda		= radeon_gpio_getsda;
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/video/matrox/i2c-matroxfb.c linux-2.6-6-rc3-mm2/drivers/video/matrox/i2c-matroxfb.c
--- xx-linux-2.6-6-rc3-mm2/drivers/video/matrox/i2c-matroxfb.c	2004-05-09 11:03:09.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/video/matrox/i2c-matroxfb.c	2004-05-09 17:50:36.000000000 +0200
@@ -104,13 +104,14 @@
 };
 
 static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, 
-		unsigned int data, unsigned int clock, const char* name) {
+		unsigned int data, unsigned int clock, const char* name, unsigned int class) {
 	int err;
 
 	b->minfo = minfo;
 	b->mask.data = data;
 	b->mask.clock = clock;
 	b->adapter = matrox_i2c_adapter_template;
+	b->class = class;
 	snprintf(b->adapter.name, I2C_NAME_SIZE, name,
 		minfo->fbcon.node);
 	i2c_set_adapdata(&b->adapter, b);
@@ -160,22 +161,22 @@
 	switch (ACCESS_FBINFO(chip)) {
 		case MGA_2064:
 		case MGA_2164:
-			err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1B_DATA, DDC1B_CLK, "DDC:fb%u #0");
+			err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1B_DATA, DDC1B_CLK, "DDC:fb%u #0", I2C_CLASS_DDC);
 			break;
 		default:
-			err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1_DATA, DDC1_CLK, "DDC:fb%u #0");
+			err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1_DATA, DDC1_CLK, "DDC:fb%u #0", I2C_CLASS_DDC);
 			break;
 	}
 	if (err)
 		goto fail_ddc1;
 	if (ACCESS_FBINFO(devflags.dualhead)) {
-		err = i2c_bus_reg(&m2info->ddc2, minfo, DDC2_DATA, DDC2_CLK, "DDC:fb%u #1");
+		err = i2c_bus_reg(&m2info->ddc2, minfo, DDC2_DATA, DDC2_CLK, "DDC:fb%u #1", I2C_CLASS_DDC);
 		if (err = -ENODEV) {
 			printk(KERN_INFO "i2c-matroxfb: VGA->TV plug detected, DDC unavailable.\n");
 		} else if (err)
 			printk(KERN_INFO "i2c-matroxfb: Could not register secondary output i2c bus. Continuing anyway.\n");
 		/* Register maven bus even on G450/G550 */
-		err = i2c_bus_reg(&m2info->maven, minfo, MAT_DATA, MAT_CLK, "MAVEN:fb%u");
+		err = i2c_bus_reg(&m2info->maven, minfo, MAT_DATA, MAT_CLK, "MAVEN:fb%u", I2C_CLASS_TV_ANALOG);
 		if (err)
 			printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n");
 	}
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/video/matrox/matroxfb_maven.c linux-2.6-6-rc3-mm2/drivers/video/matrox/matroxfb_maven.c
--- xx-linux-2.6-6-rc3-mm2/drivers/video/matrox/matroxfb_maven.c	2004-05-09 11:03:09.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/video/matrox/matroxfb_maven.c	2004-05-09 17:46:07.000000000 +0200
@@ -1297,6 +1297,7 @@
 	.name		= "maven",
 	.id		= I2C_DRIVERID_MGATVO,
 	.flags		= I2C_DF_NOTIFY,
+	.class		= I2C_CLASS_TV_ANALOG,
 	.attach_adapter	= maven_attach_adapter,
 	.detach_client	= maven_detach_client,
 	.command	= maven_command,
-------------- next part --------------
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ibm_iic.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ibm_iic.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ibm_iic.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ibm_iic.c	2004-05-09 18:19:44.000000000 +0200
@@ -607,6 +607,7 @@
 	i2c_set_adapdata(adap, dev);
 	adap->id = I2C_HW_OCP | iic_algo.id;
 	adap->algo = &iic_algo;
+	adap->class = I2C_CLASS_ALL;
 	adap->client_register = NULL;
 	adap->client_unregister = NULL;
 	adap->timeout = 1;
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-iop3xx.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-iop3xx.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-iop3xx.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-iop3xx.c	2004-05-09 18:17:57.000000000 +0200
@@ -507,18 +507,31 @@
 	.name			= ADAPTER_NAME_ROOT "0",
 	.id			= I2C_HW_IOP321,
 	.algo_data		= &algo_iop3xx_data0,
+	.class			= I2C_CLASS_ALL,
 };
 static struct i2c_adapter iop3xx_ops1 = {
 	.owner			= THIS_MODULE,
 	.name			= ADAPTER_NAME_ROOT "1",
 	.id			= I2C_HW_IOP321,
 	.algo_data		= &algo_iop3xx_data1,
+	.class			= I2C_CLASS_ALL,
 };
 
 static int __init i2c_iop3xx_init (void)
 {
-	return i2c_iop3xx_add_bus(&iop3xx_ops0) ||
-		i2c_iop3xx_add_bus(&iop3xx_ops1);
+	int ret;
+	
+	ret = i2c_iop3xx_add_bus(&iop3xx_ops0);
+	if (ret)
+		return ret;
+		
+	ret = i2c_iop3xx_add_bus(&iop3xx_ops1);
+	if (ret) {
+		i2c_iop3xx_del_bus(&iop3xx_ops0);
+		return ret;
+	}
+
+	return 0;
 }
 
 static void __exit i2c_iop3xx_exit (void)
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ite.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ite.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ite.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ite.c	2004-05-09 18:13:22.000000000 +0200
@@ -192,6 +192,7 @@
 	.owner		= THIS_MODULE,
 	.id		= I2C_HW_I_IIC,
 	.algo_data	= &iic_ite_data,
+	.class		= I2C_CLASS_ALL,
 	.dev		= {
 		.name	= "ITE IIC adapter",
 	},
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/scx200_i2c.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/scx200_i2c.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/scx200_i2c.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/scx200_i2c.c	2004-05-09 18:13:55.000000000 +0200
@@ -84,6 +84,7 @@
 static struct i2c_adapter scx200_i2c_ops = {
 	.owner		   = THIS_MODULE,
 	.algo_data	   = &scx200_i2c_data,
+	.class		   = I2C_CLASS_ALL,
 	.name	= "NatSemi SCx200 I2C",
 };
 
-------------- next part --------------
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-frodo.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-frodo.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-frodo.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-frodo.c	2004-05-09 19:56:30.000000000 +0200
@@ -62,6 +62,7 @@
 	.owner			= THIS_MODULE,
 	.id			= I2C_HW_B_FRODO,
 	.algo_data		= &bit_frodo_data,
+	.class			= I2C_CLASS_ALL,
 	.dev			= {
 		.name		= "Frodo adapter driver",
 	},
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-hydra.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-hydra.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-hydra.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-hydra.c	2004-05-09 20:04:50.000000000 +0200
@@ -107,6 +107,7 @@
 	.owner		= THIS_MODULE,
 	.name		= "Hydra i2c",
 	.id		= I2C_HW_B_HYDRA,
+	.class		= I2C_CLASS_HWMON,
 	.algo_data	= &hydra_bit_data,
 };
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-i810.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-i810.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-i810.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-i810.c	2004-05-09 19:58:12.000000000 +0200
@@ -173,6 +173,7 @@
 static struct i2c_adapter i810_i2c_adapter = {
 	.owner		= THIS_MODULE,
 	.name		= "I810/I815 I2C Adapter",
+	.class		= I2C_CLASS_ALL, /* fixme, what's the correct class? */
 	.algo_data	= &i810_i2c_bit_data,
 };
 
@@ -189,6 +190,7 @@
 static struct i2c_adapter i810_ddc_adapter = {
 	.owner		= THIS_MODULE,
 	.name		= "I810/I815 DDC Adapter",
+	.class		= I2C_CLASS_DDC,
 	.algo_data	= &i810_ddc_bit_data,
 };
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ixp4xx.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ixp4xx.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ixp4xx.c	2004-05-09 11:06:43.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-ixp4xx.c	2004-05-09 20:04:01.000000000 +0200
@@ -133,8 +133,9 @@
 	drv_data->algo_data.mdelay = 10;
 	drv_data->algo_data.timeout = 100;
 
-	drv_data->adapter.id = I2C_HW_B_IXP4XX,
-	drv_data->adapter.algo_data = &drv_data->algo_data,
+	drv_data->adapter.id = I2C_HW_B_IXP4XX;
+	drv_data->adapter.algo_data = &drv_data->algo_data;
+	drv_data->adapter.class = I2C_CLASS_ALL;
 
 	drv_data->adapter.dev.parent = &plat_dev->dev;
 
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-prosavage.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-prosavage.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-prosavage.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-prosavage.c	2004-05-09 20:00:12.000000000 +0200
@@ -181,12 +181,13 @@
 /*
  * adapter initialisation
  */
-static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
+static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg, unsigned int class)
 {
 	int ret;
 	p->adap.owner	  = THIS_MODULE;
 	p->adap.id	  = I2C_HW_B_S3VIA;
 	p->adap.algo_data = &p->algo;
+	p->adap.class	  = class;
 	p->adap.dev.parent = &dev->dev;
 	p->algo.setsda	  = bit_s3via_setsda;
 	p->algo.setscl	  = bit_s3via_setscl;
@@ -281,7 +282,7 @@
 	snprintf(bus->adap.name, sizeof(bus->adap.name),
 		"ProSavage I2C bus at %02x:%02x.%x",
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL1);
+	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL1, I2C_CLASS_ALL);
 	if (ret) {
 		goto err_adap;
 	}
@@ -292,7 +293,7 @@
 	snprintf(bus->adap.name, sizeof(bus->adap.name),
 		"ProSavage DDC bus at %02x:%02x.%x",
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL2);
+	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL2, I2C_CLASS_DDC);
 	if (ret) {
 		goto err_adap;
 	}
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-savage4.c linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-savage4.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-savage4.c	2004-05-09 11:03:02.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/busses/i2c-savage4.c	2004-05-09 20:01:31.000000000 +0200
@@ -149,6 +149,7 @@
 	.owner		= THIS_MODULE,
 	.name		= "I2C Savage4 adapter",
 	.algo_data	= &sav_i2c_bit_data,
+	.class		= I2C_CLASS_ALL, /* fixme: correct class entry? */
 };
 
 static struct pci_device_id savage4_ids[] __devinitdata = {
-------------- next part --------------
diff -ura xx-linux-2.6-6-rc3-mm2/drivers/i2c/i2c-core.c linux-2.6-6-rc3-mm2/drivers/i2c/i2c-core.c
--- xx-linux-2.6-6-rc3-mm2/drivers/i2c/i2c-core.c	2004-05-09 11:03:03.000000000 +0200
+++ linux-2.6-6-rc3-mm2/drivers/i2c/i2c-core.c	2004-05-09 21:18:35.000000000 +0200
@@ -148,8 +148,11 @@
 	list_for_each(item,&drivers) {
 		driver = list_entry(item, struct i2c_driver, list);
 		if (driver->flags & I2C_DF_NOTIFY)
-			/* We ignore the return code; if it fails, too bad */
-			driver->attach_adapter(adap);
+			if (adap->class & driver->class)
+				/* We ignore the return code; if it fails, too bad */
+				driver->attach_adapter(adap);
+			else
+				printk("i2c-core: skipping driver '%s' on adapter '%s' (class mismatch)\n",driver->name, adap->name); 
 	}
 	up(&core_lists);
 
@@ -247,7 +250,10 @@
 	if (driver->flags & I2C_DF_NOTIFY) {
 		list_for_each(item,&adapters) {
 			adapter = list_entry(item, struct i2c_adapter, list);
-			driver->attach_adapter(adapter);
+			if (adapter->class & driver->class)
+				driver->attach_adapter(adapter);
+			else
+				printk("i2c-core: skipping driver '%s' on adapter '%s' (class mismatch)\n",driver->name, adap->name); 
 		}
 	}
 

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

* Adding .class field to struct i2c_client (was Re: [PATCH][2.6]
@ 2005-05-19  6:25       ` Jon Smirl
  0 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Jean Delvare, sensors, Linux Kernel Mailing List, Greg KH

An addition to the class idea would be for clients to have priorities.
That would let me mark the bus as being for DDC. The highest priority
client would be the DDC driver. If the DDC driver can't find valid
EDID it could then fall back to letting the EEPROM driver try to find
the chip.

Something like this is important if we get a new EDID standard that
the DDC driver doesn't recognize. By letting the EEPROM driver load at
a lower priority you could still easily get to the ROM contents. Or
does it bother people if we let both EEPROM and DDC load on DDC class
buses?

-- 
Jon Smirl
jonsmirl@gmail.com

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

* [PATCH][2.6] Add command function to struct i2c_adapter
@ 2005-05-19  6:25   ` Jean Delvare
  0 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold
  Cc: sensors, Linux Kernel Mailing List, Greg KH, Andrew Morton,
	Linus Torvalds

Hi Michael,

See my various questions inline.

> the attached patch adds a command function to struct i2c_adapter,
> similar to the command function that is already there for struct
> i2c_client.

I didne't even know that. Is this command function in struct i2c_client used
somewhere? What for?

> The reason behind this is as follows:
> In the DVB subsystem, the tuners are accessed via normal kernel i2c
> drivers. One big problem is, that tuners can be wired very differently
> depending on the surrounding hardware. Currently, we need to keep
> specific settings which are unique to a hardware design in the
> independent i2c tuner driver. This is both very ugly and makes it
> impossible to support DVB drivers which are not in the official Linux
> kernel tree, but could otherwise use in-kernel frontend driver.

What is the i2c tuner driver "independent" of? Do you simply mean that it
holds the common code for all DVB adapters?

> If the struct i2c_adapter has a command function, it would be possible
> to get additional informations from the adapter in the i2c client's
> attach_adapter() function *before* probing the device and guessing
> things like i2c addresses or other hardware settings.

I see what you want to do, but I don't exactly see how it solves your problem.
Your new command callback function will provide an adapter-specific interface
to adapter internal data. You will have to fill the data before you can access
it, so there still is hardware-specific data involved. Is your point that this
data would be located in (and split among) adapter drivers instead of the
common tuner driver as is now?

I am interested in your proposal because we (the sensors side of the i2c bus)
are facing a similar problem with hardware monitoring chips on motherboads.
The same chip can be wired differently on various motherboads, and most of the
time there is no way to guess (either because the hardware just doesn't
provide any way, or because the BIOS failed to do its job properly). We have
not come to any solution yet, and most of the time users have to use
user-space tools (such as i2cset) prior to loading the drivers. Looks like the
problem you are dealing with is of similar nature.

My initial thoughts about this were that we could use DMI data and/or PCI
information to identify systems, and trigger motherboard-specific code
whenever needed. It's really just a wild guess, I don't know if it is the
correct way. Wouldn't it work for you as well?

I would appreciate if you could show us some (pseudo)code with explanations on
what you have for now, and what you would have after the change. I have some
difficulties to understand what the change would actually change, most
probably because the video and sensors sides of the i2c subsystem work rather
differently.

On a completely different matter, what about the i2c subsystem class flags and
checking mechanism? You had come with a first step some months ago (adding a
class member to i2c clients), and your proposal (generalized check of i2c
client class against adapter class) looked very good to me, but then we did
not finish the job. What about it? I am willing to help on the sensors front
if you are going into this again someday. If I remember correctly, step 2 was
about clearing manual class checks and filling all class members, and step 3
was about implementing the generalized check in i2c-core. Am I right?

Thanks.

-- 
Jean Delvare
http://khali.linux-fr.org/

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

* [PATCH][2.6] Add command function to struct i2c_adapter
@ 2005-05-19  6:25     ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Jean Delvare; +Cc: sensors, Linux Kernel Mailing List, Greg KH, linux-dvb

Hi,

(because I think this will be an in-depth discussion I trimmed the CC 
list a litte bit)

On 21.09.2004 15:28, Jean Delvare wrote:
>>the attached patch adds a command function to struct i2c_adapter,
>>similar to the command function that is already there for struct
>>i2c_client.

> I didne't even know that. Is this command function in struct i2c_client used
> somewhere? What for?

Please have a look at Video4Linux driver drivers/media/video/mxb.c. This 
driver needs various helper chipsets: tuner, tea6145c, tea6420, tda9840, 
saa7111.

For example the tea6415c is a simple video matrix chipset. If the user 
request a change of the input, the video matrix needs to be re-programmed.

For this, the tea6415 driver has the TEA6415C_SWITCH ioctl function, 
which is called through the i2c_client command() function.
 > mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);

Otherwise there would be no way the mxb driver could tell the tea6415c 
that the configuration should be changed.

>>The reason behind this is as follows:
>>In the DVB subsystem, the tuners are accessed via normal kernel i2c
>>drivers. One big problem is, that tuners can be wired very differently
>>depending on the surrounding hardware. Currently, we need to keep
>>specific settings which are unique to a hardware design in the
>>independent i2c tuner driver. This is both very ugly and makes it
>>impossible to support DVB drivers which are not in the official Linux
>>kernel tree, but could otherwise use in-kernel frontend driver.

> What is the i2c tuner driver "independent" of? Do you simply mean that it
> holds the common code for all DVB adapters?

The tuner is called frontend in dvb terms, because it holds more that 
just a simple tuner.

Some parts are hardware-independent and are in the right place in the 
frontend drivers. But manufacturers are free to use different plls (the 
actual tuners). Unfortunately, they nearly all sit on the same i2c 
address, are really dumb, write only and therefore not very distinguishable.

Currently the frontend drivers do a strcmp() on the adapter name. If it 
is "SkyStar2" for example, then it is a TechniSat card with a  Samsung 
TBMU24112IMB pll.

With that solution, it's not possible to support dvb drivers outside of 
the kernel which could theoretically use the in-kernel frontend drivers, 
because h/w dependend things need to coded into every frontend driver.

>>If the struct i2c_adapter has a command function, it would be possible
>>to get additional informations from the adapter in the i2c client's
>>attach_adapter() function *before* probing the device and guessing
>>things like i2c addresses or other hardware settings.

> I see what you want to do, but I don't exactly see how it solves your problem.
> Your new command callback function will provide an adapter-specific interface
> to adapter internal data.

Not adapter internal data, but frontend specific data, that only the 
manufacturer knows (which can be distinguished by subsystem pci ids).

 > You will have to fill the data before you can access
 > it, so there still is hardware-specific data involved. Is your point
 > that this
 > data would be located in (and split among) adapter drivers instead of
 > the
 > common tuner driver as is now?

Yes. With that approach, it's possible to support dvb drivers outside of 
the kernel, because all necessary information about the frontends is 
inside the dvb driver, not the frontend driver.

> I am interested in your proposal because we (the sensors side of the i2c bus)
> are facing a similar problem with hardware monitoring chips on motherboads.
> The same chip can be wired differently on various motherboads, and most of the
> time there is no way to guess (either because the hardware just doesn't
> provide any way, or because the BIOS failed to do its job properly). We have
> not come to any solution yet, and most of the time users have to use
> user-space tools (such as i2cset) prior to loading the drivers. Looks like the
> problem you are dealing with is of similar nature.

Yes, it's basically the same.

> My initial thoughts about this were that we could use DMI data and/or PCI
> information to identify systems, and trigger motherboard-specific code
> whenever needed. It's really just a wild guess, I don't know if it is the
> correct way. Wouldn't it work for you as well?

This is how it will work. In our case, we only need pci ids, but it's 
possible to use other information sources as well.

Let's say the user loads the stv0299 frontend driver and later the 
dvb-ttpci device driver.

The dvb-ttpci driver exports an i2c_adapter, the stv0299 
i2c_attach_adapter() function will be called. Ideally, if this isn't a 
bus from the digitial tv subsystem, then bail out (This needs to be 
implemented, see below).

If we are on a digital tv i2c bus the stv0299 uses the i2c adapter 
command() callback and asks the i2c adapter, if this frontend can be on 
that bus at all and asks for further informations.

dvb-ttpci knows the pci ids and can tell different hardware versions. 
For example, cable dvb cards have different pci ids than satellite dvb 
cards. The stv0299 is a satellite frontend, so if the bus is on a dvb 
cable card then dvb-ttpci can simply tell the stv0299 driver not to do 
anything.

If the stv0299 can be found on that system in theory, either the correct 
hardware stv0299 dependent informations are supplied completely or 
probing informations are supplied.

> I would appreciate if you could show us some (pseudo)code with explanations on
> what you have for now, and what you would have after the change. I have some
> difficulties to understand what the change would actually change, most
> probably because the video and sensors sides of the i2c subsystem work rather
> differently.

Please have a look at drivers/media/dvb/frontends/stv0299.c

At the top you'll notice a lot of defines:
#define PHILIPS_SU1278_TUA      3 // SU1278 with TUA6100 synth

In lots of functions there are switch/case statements to distinguish 
different plls, for example in pll_set_tv_freq().  stv0299_init() is 
ugly, too. The init-data for different hardware is hardcoded into the 
frontend driver. *shiver*

With the command() function, probe_tuner() with the ugly strcmp() stuff 
and i2c probing can be killed completely.

In other places, common i2c_adapter commands can be used to pull 
frontend device specific data from the dvb device (for example frequency 
boundaries) or trigger h/w dependend thinks that only the dvb driver 
knows, like setting a frequency in the pll with command(SET_PLL).

Sorry, I just have some proof-of-concept code, that doesn't use all the 
things I explained above. Some dvb people would like to give up the 
strong separation due to the kernel i2c interface and have something 
more "dvbish".

> On a completely different matter, what about the i2c subsystem class flags and
> checking mechanism? You had come with a first step some months ago (adding a
> class member to i2c clients), and your proposal (generalized check of i2c
> client class against adapter class) looked very good to me, but then we did
> not finish the job. What about it? I am willing to help on the sensors front
> if you are going into this again someday. If I remember correctly, step 2 was
> about clearing manual class checks and filling all class members, and step 3
> was about implementing the generalized check in i2c-core. Am I right?

I'll answer that in a separate mail.

> Thanks.

CU
Michael.

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

* [Fwd: [PATCH][2.6] Add command function to struct i2c_adapter]
@ 2005-05-19  6:25 Michael Hunold
  2005-05-19  6:25   ` Jean Delvare
  0 siblings, 1 reply; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: lm-sensors

Hi,

sorry I forgot to CC the sensors/i2c mailing list. Comments welcome!

Regards
Michael Hunold.
-------------- next part --------------
An embedded message was scrubbed...
From: Michael Hunold <hunold@linuxtv.org>
Subject: [PATCH][2.6] Add command function to struct i2c_adapter
Date: Mon, 20 Sep 2004 19:19:24 +0200
Size: 2880
Url: http://lists.lm-sensors.org/pipermail/lm-sensors/attachments/20040921/88091fbb/PATCH2.mht

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

* Adding .class field to struct i2c_client (was Re: [PATCH][2.6]
@ 2005-05-19  6:25       ` Greg KH
  0 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Jean Delvare, sensors, Linux Kernel Mailing List

On Tue, Sep 21, 2004 at 07:41:31PM +0200, Michael Hunold wrote:
> Please have a look and tell me what you think. The big problem will be, 
> that we cannot test all configurations, so it's possible that some 
> devices won't be recognized anymore, because the .class entries don't match.

I like the patches.  If you get them in a state you like (and drop the
printk(), and use dev_dbg() instead), and send them 1 patch per file
with the Signed-off-by: line, I'll be glad to apply them.

thanks,

greg k-h

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

* Adding .class field to struct i2c_client (was Re: [PATCH][2.6]
@ 2005-05-19  6:25         ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Greg KH; +Cc: Jean Delvare, sensors, Linux Kernel Mailing List

Hi,

On 24.09.2004 02:02, Greg KH wrote:
> On Tue, Sep 21, 2004 at 07:41:31PM +0200, Michael Hunold wrote:
> 
>>Please have a look and tell me what you think. The big problem will be, 
>>that we cannot test all configurations, so it's possible that some 
>>devices won't be recognized anymore, because the .class entries don't match.

> I like the patches.  If you get them in a state you like (and drop the
> printk(), and use dev_dbg() instead), 

Ok.

> and send them 1 patch per file
> with the Signed-off-by: line, I'll be glad to apply them.

I'll re-create them against 2.6.9-rc2-mm2.

Do you really mean one patch per file, ie. about 50 separate patches? (I 
don't care, I simply write a script that splits them up)

> thanks,
> greg k-h

CU
Michael.

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

* Adding .class field to struct i2c_client (was Re: [PATCH][2.6]
@ 2005-05-19  6:25           ` Greg KH
  0 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Jean Delvare, sensors, Linux Kernel Mailing List

On Fri, Sep 24, 2004 at 08:22:34AM +0200, Michael Hunold wrote:
> Hi,
> 
> On 24.09.2004 02:02, Greg KH wrote:
> >On Tue, Sep 21, 2004 at 07:41:31PM +0200, Michael Hunold wrote:
> >
> >>Please have a look and tell me what you think. The big problem will be, 
> >>that we cannot test all configurations, so it's possible that some 
> >>devices won't be recognized anymore, because the .class entries don't 
> >>match.
> 
> >I like the patches.  If you get them in a state you like (and drop the
> >printk(), and use dev_dbg() instead), 
> 
> Ok.
> 
> >and send them 1 patch per file
> >with the Signed-off-by: line, I'll be glad to apply them.
> 
> I'll re-create them against 2.6.9-rc2-mm2.
> 
> Do you really mean one patch per file, ie. about 50 separate patches? (I 
> don't care, I simply write a script that splits them up)

Sorry, I ment one email per patch (you sent more than one patch in that
email.)

thanks,

greg k-h

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-10-01  6:52           ` Greg KH
@ 2004-10-01 12:22             ` Adrian Cox
  -1 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Greg KH; +Cc: Michael Hunold, linux-kernel, sensors

On Fri, 2004-10-01 at 07:52, Greg KH wrote:
> On Fri, Sep 24, 2004 at 10:21:08PM +0200, Michael Hunold wrote:

> > If we have a PCI card where we exactly know what we are doing, we can 
> > use the NO_PROBE flag to effectively block any probing and can use the 
> > proposed interface to manually connect the clients.
> 
> But why?  The .class feature can accomplish this too.  Just create a new
> class for this type of adapter and device.  Then only that device will
> be able to be connected to that adapter, just like you want to have
> happen, right?

Either the i2c devices need to be able to support a list of permitted
adapters, or the i2c adapters need a list of permitted clients. A single
class isn't adequate. Consider the following scenario:

The FooTV123 has multiplexor MX3R0K3 and frontend XYZZY, the TVMatic3000
has frontend XYZZY and multiplexor MX31337, and the FooTV124 has
multiplexor MX31337 and frontend FR012. All three cards are installed in
the same machine. In the worst case the probe code for MX31337 puts
MX3R0K3 into a state that requires a hard reset.

Manual connection of clients makes it easier to develop a driver outside
the kernel tree, then merge it when ready, without having to allocate a
number from a central authority.

Creating the adapter with a list of permitted clients is also an
adequate solution for a bus like I2C which doesn't properly support
probing. The OCP bus on PowerPC has no explicit probing, and uses a
similar approach of creating the bus with a list of the devices possible
for that PowerPC model.

- Adrian Cox
Humboldt Solutions Ltd.


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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-10-01 12:22             ` Adrian Cox
@ 2004-10-01 13:57               ` Jean Delvare
  -1 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox, Greg KH; +Cc: Michael Hunold, linux-kernel, sensors

On Fri, 01 Oct 2004 13:22:45 +0100, Adrian Cox wrote
> Either the i2c devices need to be able to support a list of permitted
> adapters, or the i2c adapters need a list of permitted clients. A single
> class isn't adequate. Consider the following scenario:
> 
> The FooTV123 has multiplexor MX3R0K3 and frontend XYZZY, the TVMatic3000
> has frontend XYZZY and multiplexor MX31337, and the FooTV124 has
> multiplexor MX31337 and frontend FR012. All three cards are 
> installed in the same machine. In the worst case the probe code for 
> MX31337 puts MX3R0K3 into a state that requires a hard reset.
> 
> Manual connection of clients makes it easier to develop a driver outside
> the kernel tree, then merge it when ready, without having to 
> allocate a number from a central authority.

Agreed. Greg's proposal would somehow mean one class per video device adapter,
which doesn't sound good. We have room for only 32 classes anyway. However, I
agree with Greg that a "no probe" flag isn't needed if we already have
well-defined classes.

Basically, probing is something only hardware monitoring chip drivers do (+
eeprom, so we can include the DDC world). Video clients don't probe as far as
I know (because probing just doesn't work here). So, if we were to have a "no
probe" flag, it would always be clear when class is VIDEO and always set when
class is HWMON (I voluntarily simplify, there are a couple more classes), so
it means that the "no probe" flag is redundant. To put it short, simply not
declaring an adapter as class HWMON means it won't be probed ever (the eeprom
case is to be considered separately and may require a class of its own).

> Creating the adapter with a list of permitted clients is also an
> adequate solution for a bus like I2C which doesn't properly support
> probing. The OCP bus on PowerPC has no explicit probing, and uses a
> similar approach of creating the bus with a list of the devices possible
> for that PowerPC model.

This may be fine for the PPC world, but in the i386 world it wont work. To
give you an idea, the MBM database has 1155 motherboards listed, most of which
have hardware monitoring chips on-board. It happens quite often that I don't
find motherboard models I am looking for therein, so a complete base would
have maybe 1500 or 2000 entries. We certainly don't want to have such a base
in the linux kernel tree. It would be unmaintainable, and also would ensure
that new hardware has no chance to work until us developers know about it.
Probing is the way to go there, even if the I2C bus was obviously not designed
for this.

So I2C bus probing won't go away. Classes or flags are what we need (unless we
go for separated I2C adapter lists, but that's a completely different
approach, and obviously we are not interested until someone comes with a solid
patch that really does this.) A working classes system is really next door,
Michael did most of the work already, half of which is already merged into the
kernel tree.

Thanks.

-- 
Jean Delvare
http://khali.linux-fr.org/

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-10-01 12:22             ` Adrian Cox
@ 2004-10-01 23:41               ` Greg KH
  -1 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Michael Hunold, linux-kernel, sensors

On Fri, Oct 01, 2004 at 01:22:45PM +0100, Adrian Cox wrote:
> On Fri, 2004-10-01 at 07:52, Greg KH wrote:
> > On Fri, Sep 24, 2004 at 10:21:08PM +0200, Michael Hunold wrote:
> 
> > > If we have a PCI card where we exactly know what we are doing, we can 
> > > use the NO_PROBE flag to effectively block any probing and can use the 
> > > proposed interface to manually connect the clients.
> > 
> > But why?  The .class feature can accomplish this too.  Just create a new
> > class for this type of adapter and device.  Then only that device will
> > be able to be connected to that adapter, just like you want to have
> > happen, right?
> 
> Either the i2c devices need to be able to support a list of permitted
> adapters, or the i2c adapters need a list of permitted clients. A single
> class isn't adequate. Consider the following scenario:
> 
> The FooTV123 has multiplexor MX3R0K3 and frontend XYZZY, the TVMatic3000
> has frontend XYZZY and multiplexor MX31337, and the FooTV124 has
> multiplexor MX31337 and frontend FR012. All three cards are installed in
> the same machine. In the worst case the probe code for MX31337 puts
> MX3R0K3 into a state that requires a hard reset.
> 
> Manual connection of clients makes it easier to develop a driver outside
> the kernel tree, then merge it when ready, without having to allocate a
> number from a central authority.

Ok, I now understand better, thanks for putting up with me :)

So, got a patch to do this?

thanks,

greg k-h

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 15:40                   ` Jon Smirl
@ 2004-09-22 15:56                     ` Adrian Cox
  -1 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

On Wed, 2004-09-22 at 16:40, Jon Smirl wrote:

> Any DDC solution needs to leave the data visible in sysfs and
> accessible from user space. I'm trying to move the EDID parsing code
> out of the kernel.

Would it do for a display device to expose read-only EDID data through
sysfs, or do you need I2C level access to DDC from userspace?

- Adrian Cox
Humboldt Solutions Ltd.


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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 15:56                     ` Adrian Cox
@ 2004-09-22 16:07                       ` Jon Smirl
  -1 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

On Wed, 22 Sep 2004 16:56:19 +0100, Adrian Cox <adrian@humboldt.co.uk> wrote:
> Would it do for a display device to expose read-only EDID data through
> sysfs, or do you need I2C level access to DDC from userspace?

For my purpose of decoding the EDID read only access is fine. 

But I do know there are programs that use the user space I2C drivers
to control extended monitor functions. Some monitors let you set
brightnesss, contrast, on/off via the I2C link.

-- 
Jon Smirl
jonsmirl@gmail.com

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 16:07                       ` Jon Smirl
@ 2004-09-22 16:51                         ` Adrian Cox
  -1 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

On Wed, 2004-09-22 at 17:07, Jon Smirl wrote:
> On Wed, 22 Sep 2004 16:56:19 +0100, Adrian Cox <adrian@humboldt.co.uk> wrote:
> > Would it do for a display device to expose read-only EDID data through
> > sysfs, or do you need I2C level access to DDC from userspace?
> 
> For my purpose of decoding the EDID read only access is fine. 
> 
> But I do know there are programs that use the user space I2C drivers
> to control extended monitor functions. Some monitors let you set
> brightnesss, contrast, on/off via the I2C link.

In which case you will need the current mechanism, with the class
mechanism to stop sensor drivers probing the bus.

- Adrian Cox
Humboldt Solutions Ltd.


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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 16:51                         ` Adrian Cox
@ 2004-09-22 17:17                           ` Jon Smirl
  -1 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

Can this code be implemented in the current framework? Don't I need
the attach/detach_adapter hook which I can't get to from the algo_bit
code?

http://lkml.org/lkml/2004/9/21/181

-- 
Jon Smirl
jonsmirl@gmail.com

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 13:38                 ` Jean Delvare
@ 2004-09-22 18:32                   ` Adrian Cox
  -1 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Linux Kernel Mailing List, sensors; +Cc: Michael Hunold, Jon Smirl, Greg KH

On Wed, 2004-09-22 at 14:38, Jean Delvare wrote:

> Aha, this is an interesting point (which was missing from your previous
> explanation). The base of your proposal would be to have several small i2c
> "trees" (where a tree is a list of adapters and a list of clients) instead of
> a larger, unique one. This would indeed solve a number of problems, and I
> admit that it is somehow equivalent to Michael's classes in that it
> efficiently prevents the hardware monitoring clients from probing the video
> stuff. The rest is just details internal to each "tree". As I understand it,
> each video device would be a tree on itself, while the whole hardware
> monitoring stuff would constitute one (bigger) tree. Correct?

I've been rereading the code, and it could be even simpler. How about
this:

1) The card driver defines an i2c_adapter structure, but never calls
i2c_add_adapter(). The only extra thing it needs to do is to initialise
the semaphores in the structure.
2) The frontend calls i2c_transfer() directly.
3) The i2c core never gets involved, and there is never any i2c_client
structure.

This gives us the required reuse of the I2C algo-bit code, without any
of the list walking or device probing being required.

- Adrian Cox
Humboldt Solutions Ltd.


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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 16:51                         ` Adrian Cox
@ 2004-09-22 18:55                           ` Jean Delvare
  -1 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox
  Cc: Jon Smirl, Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

> > For my purpose of decoding the EDID read only access is fine. 
> > 
> > But I do know there are programs that use the user space I2C drivers
> > to control extended monitor functions. Some monitors let you set
> > brightnesss, contrast, on/off via the I2C link.
> 
> In which case you will need the current mechanism, with the class
> mechanism to stop sensor drivers probing the bus.

There is no absolute necessity to do that as far as I can see. Usually,
there is nothing on the DDC bus but the DDC EEPROM itself, so the probes
won't happen except for the EEPROM itself, for which it is safe.

-- 
Jean "Khali" Delvare
http://khali.linux-fr.org/

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 18:32                   ` Adrian Cox
@ 2004-09-22 20:04                     ` Mark M. Hoffman
  -1 siblings, 0 replies; 76+ messages in thread
From: Mark M. Hoffman @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox
  Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Jon Smirl, Greg KH

Hi Adrian:

* Adrian Cox <adrian@humboldt.co.uk> [2004-09-22 19:32:31 +0100]:
> On Wed, 2004-09-22 at 14:38, Jean Delvare wrote:
> 
> > Aha, this is an interesting point (which was missing from your previous
> > explanation). The base of your proposal would be to have several small i2c
> > "trees" (where a tree is a list of adapters and a list of clients) instead of
> > a larger, unique one. This would indeed solve a number of problems, and I
> > admit that it is somehow equivalent to Michael's classes in that it
> > efficiently prevents the hardware monitoring clients from probing the video
> > stuff. The rest is just details internal to each "tree". As I understand it,
> > each video device would be a tree on itself, while the whole hardware
> > monitoring stuff would constitute one (bigger) tree. Correct?
> 
> I've been rereading the code, and it could be even simpler. How about
> this:
> 
> 1) The card driver defines an i2c_adapter structure, but never calls
> i2c_add_adapter(). The only extra thing it needs to do is to initialise
> the semaphores in the structure.
> 2) The frontend calls i2c_transfer() directly.
> 3) The i2c core never gets involved, and there is never any i2c_client
> structure.

Yes, almost...

Why force your card driver to re-implement i2c_smbus_read_byte() and all
its relatives?  Go ahead and define the i2c_client structure(s) as well,
but don't i2c_attach_client().  Sensors drivers do their probing before
attaching the client, so I know that works.

> This gives us the required reuse of the I2C algo-bit code, without any
> of the list walking or device probing being required.

Ditto, *plus* you can still reuse all the i2c_core helper routines that
require a client structure.

Regards,

-- 
Mark M. Hoffman
mhoffman@lightlink.com

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 11:54               ` Adrian Cox
@ 2004-09-23  7:09                 ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Jon Smirl, Greg KH

Hi,

On 22.09.2004 13:54, Adrian Cox wrote:
> Not in the current Linux DVB code. A frontend driver registers itself
> onto a list, and whenever a DVB card registers its I2C adapter the
> available frontends are probed. My solution would throw away all the
> list handling in dvb_i2c.c entirely.

Kernels including 2.6.9-rc2-mm1 have the proprietary dvb_i2c 
implementation inside, ie. no kernel i2c at all. I have recently sent a 
patch to Andrew that converts all dvb drivers and frontends to fully use 
kernel i2c. The current discussion is completely about the 
not-yet-officially-released dvb subsystem using kernel-i2c.

>>All in all I don't see how we can solve the problem without either a "do not
>>probe" flag in the adapter structure or a class bitfield in both the adapter
>>and the client structures. I would be fine with either option unless someone
>>explains how one is better than the other in any particular case.

> What I want is a way for a card driver to create a private I2C adapter,
> and private instances of I2C clients, for purposes of code reuse. The
> card driver would be responsible for attaching those clients to the bus
> and cleaning up the objects on removal. The bus wouldn't be visible in
> sysfs, or accessible from user-mode.

We're having a similar discussion on the linux-dvb mailing list and I 
have made a similar suggestion. There shouldn't be such a thing as a 
generic i2c bus at all - at least not for specific PCI or AGP cards 
having an i2c bus, because you really now what's there.

The adapters should be able to create a specific i2c bus. This bus then 
should have a well-defined client<->adapter interface. The adapter 
provides an interface clients can use for example to query h/w dependent 
informations, like "Is it possible to have chipset XY on your bus?". For 
DVB this question can be answered using pci subvendor/subdevice 
informations. This avoids the need to add a command() function to struct 
i2c_adapter.

If the adapter wants a client to join the bus and the client is really 
found, then the client must provide a well-defined set of functions as 
well. The adapter can then control the device in a type-safe manner and 
doesn't have to control it using the current ioctl interface.

> - Adrian Cox
> Humboldt Solutions Ltd.

We need to keep in mind, that the adapter interface must be a per-client 
interface. On PCI devices it's simple: you have a i2c bus bound to a dvb 
card and know which chipsets can be there. The bus is dvb specific.

On embedded platforms, however, you usually have one one i2c bus, where 
everything is present: dvb frontends, audio/video multiplexers, 
digital/analog audio converters, stuff like that.

So if you create *the* i2c bus and invite i2c client to participate at 
the party, you need to provide different interfaces to the different 
chipsets.

CU
Michael.

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 18:32                   ` Adrian Cox
@ 2004-09-23  7:41                     ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Jon Smirl, Greg KH

Hi,

On 22.09.2004 20:32, Adrian Cox wrote:
>>Aha, this is an interesting point (which was missing from your previous
>>explanation). The base of your proposal would be to have several small i2c
>>"trees" (where a tree is a list of adapters and a list of clients) instead of
>>a larger, unique one. This would indeed solve a number of problems, and I
>>admit that it is somehow equivalent to Michael's classes in that it
>>efficiently prevents the hardware monitoring clients from probing the video
>>stuff. The rest is just details internal to each "tree". As I understand it,
>>each video device would be a tree on itself, while the whole hardware
>>monitoring stuff would constitute one (bigger) tree. Correct?

> I've been rereading the code, and it could be even simpler. How about
> this:
> 
> 1) The card driver defines an i2c_adapter structure, but never calls
> i2c_add_adapter(). The only extra thing it needs to do is to initialise
> the semaphores in the structure.
> 2) The frontend calls i2c_transfer() directly.
> 3) The i2c core never gets involved, and there is never any i2c_client
> structure.
> 
> This gives us the required reuse of the I2C algo-bit code, without any
> of the list walking or device probing being required.

This is the way the linux-dvb guys are currently favouring.

In some cases there should be an adapter that has been registered with 
i2c_add_adapter() because there can always be other drivers (audio/video 
multiplexes and the like) that you cannot get your hands on because they 
are provided by the manufacturer of some embedded platform.

For some cards (mostly bt8x8 based, ie. the core parts are driven by the 
"bttv" driver) and hybrid cards (ie. dvb cards that have a separate 
analog video input) the common i2c bus cannot go away, but it should be 
protected by proper .class entries in both the clients and adapters.

We think about splitting the frontend drivers into library parts, ie. 
library functions for demodulators (the current frontend drivers) and 
h/w dependent plls (or tuners).

Because of the fact the pci device knows which devices are present on 
the bus, it can register and configure the demod, pll and other specific 
dvb devices with direct i2c_transfer()s directly. If there are multiple 
combinations possible, it can use the library to probe as well.

The question we are currently facing is: are the frontend or demod i2c 
drivers real and independent i2c clients like thermal sensors or are 
they part of a h/w dependent design that should better be configured on 
a library basis?

If they are independend, then we need i2c bus types and type-safe 
client<=>adapter communication to exchange configuration and control 
informations, because the ioctl interface currently works from the 
adapter to the client and is not type safe.
Another question is, if this is probably too bloated. Think of simple 
matrix switch chipsets: the only "interface" they have is "set input a 
to output b".

> - Adrian Cox
> Humboldt Solutions Ltd.

CU
Michael.

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 18:32                   ` Adrian Cox
@ 2004-09-23  7:48                     ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Jon Smirl, Greg KH

Hi,

On 22.09.2004 20:32, Adrian Cox wrote:
>>Aha, this is an interesting point (which was missing from your previous
>>explanation). The base of your proposal would be to have several small i2c
>>"trees" (where a tree is a list of adapters and a list of clients) instead of
>>a larger, unique one. This would indeed solve a number of problems, and I
>>admit that it is somehow equivalent to Michael's classes in that it
>>efficiently prevents the hardware monitoring clients from probing the video
>>stuff. The rest is just details internal to each "tree". As I understand it,
>>each video device would be a tree on itself, while the whole hardware
>>monitoring stuff would constitute one (bigger) tree. Correct?

> I've been rereading the code, and it could be even simpler. How about
> this:
> 
> 1) The card driver defines an i2c_adapter structure, but never calls
> i2c_add_adapter(). The only extra thing it needs to do is to initialise
> the semaphores in the structure.
> 2) The frontend calls i2c_transfer() directly.
> 3) The i2c core never gets involved, and there is never any i2c_client
> structure.
> 
> This gives us the required reuse of the I2C algo-bit code, without any
> of the list walking or device probing being required.

This is the way the linux-dvb guys are currently favouring.

In some cases there should be an adapter that has been registered with 
i2c_add_adapter() because there can always be other drivers (audio/video 
multiplexes and the like) that you cannot get your hands on because they 
are provided by the manufacturer of some embedded platform.

For some cards (mostly bt8x8 based, ie. the core parts are driven by the 
"bttv" driver) and hybrid cards (ie. dvb cards that have a separate 
analog video input) the common i2c bus cannot go away, but it should be 
protected by proper .class entries in both the clients and adapters.

We think about splitting the frontend drivers into library parts, ie. 
library functions for demodulators (the current frontend drivers) and 
h/w dependent plls (or tuners).

Because of the fact the pci device knows which devices are present on 
the bus, it can register and configure the demod, pll and other specific 
dvb devices with direct i2c_transfer()s directly. If there are multiple 
combinations possible, it can use the library to probe as well.

The question we are currently facing is: are the frontend or demod i2c 
drivers real and independent i2c clients like thermal sensors or are 
they part of a h/w dependent design that should better be configured on 
a library basis?

If they are independend, then we need i2c bus types and type-safe 
client<=>adapter communication to exchange configuration and control 
informations, because the ioctl interface currently works from the 
adapter to the client and is not type safe.
Another question is, if this is probably too bloated. Think of simple 
matrix switch chipsets: the only "interface" they have is "set input a 
to output b".

> - Adrian Cox
> Humboldt Solutions Ltd.

CU
Michael.

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-23  7:09                 ` Michael Hunold
@ 2004-09-23 20:18                   ` Adrian Cox
  -1 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Linux Kernel Mailing List, sensors, Jon Smirl, Greg KH

On Thu, 2004-09-23 at 08:09, Michael Hunold wrote:
> We need to keep in mind, that the adapter interface must be a per-client 
> interface. On PCI devices it's simple: you have a i2c bus bound to a dvb 
> card and know which chipsets can be there. The bus is dvb specific.
> 
> On embedded platforms, however, you usually have one one i2c bus, where 
> everything is present: dvb frontends, audio/video multiplexers, 
> digital/analog audio converters, stuff like that.
> 
> So if you create *the* i2c bus and invite i2c client to participate at 
> the party, you need to provide different interfaces to the different 
> chipsets.

I may have to solve a similar problem when connecting an image sensor
directly to an embedded processor. My current idea looks a bit like
this:

1) The I2C bus is a platform device, created at boot time, independent
of my video capture module.
2) My module contains a dummy I2C driver, which exists solely to grab an
i2c_adapter pointer for the platform I2C device.

My underlying libraries don't have to worry whether the i2c_adapter came
from a parent PCI device or a platform device. My only worry is that
power management may still provide us with a headache, as we'll have to
cope with platform devices being suspended in any order.

- Adrian Cox
Humboldt Solutions Ltd.


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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-21 15:41   ` Greg KH
@ 2004-09-24 17:06     ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Greg KH; +Cc: Michael Hunold, Linux Kernel Mailing List, sensors

Hi,

On 21.09.2004 17:41, Greg KH wrote:
> On Mon, Sep 20, 2004 at 07:19:24PM +0200, Michael Hunold wrote:
> 
>> 
>>+	/* a ioctl like command that can be used to perform specific functions
>>+	 * with the adapter.
>>+	 */
>>+	int (*command)(struct i2c_adapter *adapter, unsigned int cmd, void *arg);
> 
> 
> Ick ick ick.  We don't like ioctls for the very reason they aren't type
> safe, and you can pretty much stick anything in there you want.  So
> let's not try to add the same type of interface to another subsystem.

Ok, Gerd Knorr and I have been discussing this and we have come up with 
the following idea.

We like to have an completly isolated i2c adapter, where the device 
driver can invite i2c drivers to connect an i2c client to. When the 
connection is made, an "interface" pointer with client-specific data or 
function pointers can be provided.

- i2c adapter and i2c clients register themselves as usual

- add a new NO_PROBE flag to struct i2c_adapter, so a particular adapter 
is never probed by anyone

- add these two functions to struct i2c_driver:
int (*connect)(struct i2c_adapter *adapter, void *interface, struct 
i2c_client **client);
int (*disconnect)(struct i2c_client *client);

- add new generic i2c functions:
struct i2c_driver* i2c_driver_get(char *name);
void i2c_driver_put(struct i2c_driver *drv);

- the dvb-ttpci driver now can do the following:

struct stv0299_interface {
	struct dvb_adapter *dvb_adap;
	int tuner_addr;
};

struct stv0299_interface s_if;
struct i2c_driver *drv;
struct i2c_client *clt;

request_module("stv0299");
drv = i2c_driver_get("stv0299");
// fill s_if here
drv->connect(adap, &s_if, &clt);

Now inside the "connect" function of the stv0299 demodulator i2c driver 
the device is probed, registered to the adapter and the pointer to the 
interface with the h/w dependend information is stored.

> thanks,
> greg k-h

The crucial point is probably the void * interface pointer, isn't it? Is 
this a no-no in this situation?

The dvb-ttpci driver is inviting a very specific driver, no probing 
involved. The driver interface is well-defined and will only be hidden 
behind the void * pointer to avoid a functional reference to the 
demodulator driver.

We have discussed simply adding a type-safe stv0299-specific connect 
function as well, but that would introduce a functional dependency. The 
dvb-ttpci driver can be used with about 8 different frontend drivers, so 
loading the driver would cause unnecessary frontend drivers to be loaded 
as well.

CU
Michael.

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-24 17:06     ` Michael Hunold
@ 2004-09-24 18:05       ` Jean Delvare
  -1 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Greg KH, linux-kernel, sensors

> We like to have an completly isolated i2c adapter, where the device 
> driver can invite i2c drivers to connect an i2c client to. When the 
> connection is made, an "interface" pointer with client-specific data
> or function pointers can be provided.
> (...)
> - add a new NO_PROBE flag to struct i2c_adapter, so a particular
> adapter is never probed by anyone

I don't get it. If the adapter is isolated, there is no way the i2c-core
will probe it anyway. As Adrian Cox underlined, it should be far easier
and more efficient to separate these adapters from the main i2c adapters
list from the beginning than leaving them in the main list and then try
and prevent future probings using a flag.

Also, how does this proposal interact with the work on the i2c classes?
Although the classes carry more information than a simple flag or a
complete separation, both were/may be introduced to achieve the same
goal, isn't it?

Thanks,

-- 
Jean "Khali" Delvare
http://khali.linux-fr.org/

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-24 18:05       ` Jean Delvare
@ 2004-09-24 20:21         ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: linux-kernel, sensors; +Cc: Greg KH

Hi,

On 24.09.2004 20:05, Jean Delvare wrote:
>>We like to have an completly isolated i2c adapter, where the device 
>>driver can invite i2c drivers to connect an i2c client to. When the 
>>connection is made, an "interface" pointer with client-specific data
>>or function pointers can be provided.
>>(...)
>>- add a new NO_PROBE flag to struct i2c_adapter, so a particular
>>adapter is never probed by anyone

> I don't get it. If the adapter is isolated, there is no way the i2c-core
> will probe it anyway. As Adrian Cox underlined, it should be far easier
> and more efficient to separate these adapters from the main i2c adapters
> list from the beginning than leaving them in the main list and then try
> and prevent future probings using a flag.

There a two scenarios, where you don't have full control over the i2c 
adapter or you don't want to fully isolate the bus:

1) Some dvb drivers are bttv-sub-drivers, ie. bttv does the pci and i2c 
handling by itself. You have the struct i2c_adapter pointer, but it has 
been registered by bttv, most likely as an analog and/or digital tv i2c bus.

2) Embedded platforms have usually a system-wide i2c bus, so you cannot 
isolate the bus here.

It's useful to register both adapters and drivers to the i2c-core, so 
you keep the door open.

> Also, how does this proposal interact with the work on the i2c classes?
> Although the classes carry more information than a simple flag or a
> complete separation, both were/may be introduced to achieve the same
> goal, isn't it?

Partly, yes.

The .class approach is necessary to have a finer grained access control 
by the i2c-core regarding bus classes, ie. not the client drivers have 
to check if the bus should be probed (for example dcc drivers on a dvb 
bus). This is useful in general.

If we have a PCI card where we exactly know what we are doing, we can 
use the NO_PROBE flag to effectively block any probing and can use the 
proposed interface to manually connect the clients.

> Thanks,

CU
Michael.

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-24 20:21         ` Michael Hunold
@ 2004-10-01  6:52           ` Greg KH
  -1 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold; +Cc: linux-kernel, sensors

On Fri, Sep 24, 2004 at 10:21:08PM +0200, Michael Hunold wrote:
> >Also, how does this proposal interact with the work on the i2c classes?
> >Although the classes carry more information than a simple flag or a
> >complete separation, both were/may be introduced to achieve the same
> >goal, isn't it?
> 
> Partly, yes.
> 
> The .class approach is necessary to have a finer grained access control 
> by the i2c-core regarding bus classes, ie. not the client drivers have 
> to check if the bus should be probed (for example dcc drivers on a dvb 
> bus). This is useful in general.
> 
> If we have a PCI card where we exactly know what we are doing, we can 
> use the NO_PROBE flag to effectively block any probing and can use the 
> proposed interface to manually connect the clients.

But why?  The .class feature can accomplish this too.  Just create a new
class for this type of adapter and device.  Then only that device will
be able to be connected to that adapter, just like you want to have
happen, right?

thanks,

greg k-h

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-20 17:19 [PATCH][2.6] Add command function to struct i2c_adapter Michael Hunold
@ 2004-09-21 15:41   ` Greg KH
  0 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold
  Cc: Linux Kernel Mailing List, Andrew Morton, Linus Torvalds, sensors

On Mon, Sep 20, 2004 at 07:19:24PM +0200, Michael Hunold wrote:
>  
> +	/* a ioctl like command that can be used to perform specific functions
> +	 * with the adapter.
> +	 */
> +	int (*command)(struct i2c_adapter *adapter, unsigned int cmd, void *arg);

Ick ick ick.  We don't like ioctls for the very reason they aren't type
safe, and you can pretty much stick anything in there you want.  So
let's not try to add the same type of interface to another subsystem.

How about we add the exact explicit functionality that you want, one
function per "type" of operation, like all other subsystems have.

thanks,

greg k-h

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-21 15:41   ` Greg KH
@ 2004-09-21 17:10     ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Greg KH
  Cc: Michael Hunold, Linux Kernel Mailing List, Andrew Morton,
	Linus Torvalds, sensors

Hi,

On 21.09.2004 17:41, Greg KH wrote:
> On Mon, Sep 20, 2004 at 07:19:24PM +0200, Michael Hunold wrote:
> 
>> 
>>+	/* a ioctl like command that can be used to perform specific functions
>>+	 * with the adapter.
>>+	 */
>>+	int (*command)(struct i2c_adapter *adapter, unsigned int cmd, void *arg);

> Ick ick ick.  We don't like ioctls for the very reason they aren't type
> safe, and you can pretty much stick anything in there you want.  So
> let's not try to add the same type of interface to another subsystem.

Ok.

> How about we add the exact explicit functionality that you want, one
> function per "type" of operation, like all other subsystems have.

Hm, but the functionality depends heavily on the types of clients and 
adapters.

For the dvb subsystem, for example, if we know that the i2c adapter is 
some sort of dvb device, we might need to set the pll from the frontend 
i2c client if the user wants to tune to some frequency. The pll settings 
are very h/w specific, so they should be in the driver implementing the 
i2c adapter. So from the dvb frontend dvb i2c client we would call 
adapter->command(adapter, DVB_FE_SET_PLL, &arg).

You don't mean to add a int(*dvb_fe_set_pll)(...) function to the struct 
i2c_adapter instead, don't you?

Isn't this is a general problem? Isn't there the need to have some 
abstraction to allow message passing between i2c clients and i2c 
adapters in both ways, because i2c clients are never that independend 
from the i2c adapter and have always some h/w dependend parts inside?

> thanks,
> greg k-h

Regards
Michael.

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-21 17:10     ` Michael Hunold
@ 2004-09-21 17:39       ` Jon Smirl
  -1 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold
  Cc: Greg KH, Michael Hunold, Linux Kernel Mailing List,
	Andrew Morton, Linus Torvalds, sensors

There is a related I2C problem with EEPROMs and DDC monitors. DDC
monitors look just like EEPROMs, the EEPROM driver can even read most
of them. But there are DDC monitors that need special wakeup sequences
before their ROMs will appear.

EEPROM and DDC are both algo_bit clients. When you attach a bus to
algo_bit both clients will run. There is concern that sending the
special DDC wake up sequence down non-DDC buses might mess up the bus.

A proposal was made to implement different classes of algo_bit clients
but this was never implemented. Would a class solution help with the
dvb problem too?


-- 
Jon Smirl
jonsmirl@gmail.com

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-21 17:39       ` Jon Smirl
@ 2004-09-21 18:05         ` Michael Hunold
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Greg KH, Michael Hunold, Linux Kernel Mailing List,
	Andrew Morton, Linus Torvalds, sensors

Hi,

On 21.09.2004 19:39, Jon Smirl wrote:
> There is a related I2C problem with EEPROMs and DDC monitors. DDC
> monitors look just like EEPROMs, the EEPROM driver can even read most
> of them. But there are DDC monitors that need special wakeup sequences
> before their ROMs will appear.
> 
> EEPROM and DDC are both algo_bit clients. When you attach a bus to
> algo_bit both clients will run. There is concern that sending the
> special DDC wake up sequence down non-DDC buses might mess up the bus.
> 
> A proposal was made to implement different classes of algo_bit clients
> but this was never implemented. Would a class solution help with the
> dvb problem too?

It would help to separate dvb clients and dvb busses. I just posted 
another mail titled "Adding .class field to struct i2c_client (was Re: 
[PATCH][2.6] Add command function to struct i2c_adapter" that adds a 
.class entry to the struct i2c_client.

With that addition, it's possible for the i2c core to check if the 
.class entries of the adapter and the client match. If they don't then 
there is no need to probe a driver. This will help to keep non-i2c 
drivers to be probed on dvb i2c busses (and screw them up accidently). 
Currently it's up to the driver to decide wheter to probe a bus or not.

CU
Michael.

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-21 17:39       ` Jon Smirl
@ 2004-09-21 20:33         ` Jean Delvare
  -1 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Michael Hunold, Greg KH, linux-kernel, sensors

> There is a related I2C problem with EEPROMs and DDC monitors. DDC
> monitors look just like EEPROMs, the EEPROM driver can even read most
> of them. But there are DDC monitors that need special wakeup sequences
> before their ROMs will appear.
> 
> EEPROM and DDC are both algo_bit clients.

Not true. algo-bit refers to i2c bus implementations, not i2c clients.
It happens that all DDC monitors are accessed through bit-banging I2C
busses (real I2C busses, as opposed to SMBus), but other EEPROMs do not.
Most EEPROMs are from memory modules and hang off the motherboard SMBus
(which by definition does not depend on algo-bit).

> When you attach a bus to algo_bit both clients will run.

FYI, there is no ddcmon driver in Linux 2.6 and I believe there won't
be. The eeprom driver should do the job. Converting the EEPROM data to
significant info belongs to user-space.

> There is concern that sending the
> special DDC wake up sequence down non-DDC buses might mess up the bus.

This is however true, and I agree that Michael's proposal could help in
this respect. And I actually believe that his I2C classes implementation
would help more than the "command" callback. After all, you need the DDC
data to identify the monitor, and (in some cases) need to know the
monitor to properly access the DDC data...

(BTW, I am not certain at all that we should add support for these
broken monitors. As far as I can see, they do not support the DDC
standard, too bad for them. I would hate to break standard-compliant
monitors by implementing tricks to support non-standard ones.)

> A proposal was made to implement different classes of algo_bit clients
> but this was never implemented. Would a class solution help with the
> dvb problem too?

As a side note, the classes apply to all I2C adapters, not just
bit-banging ones. And classes apply to the busses purposes (video, ddc,
sensors etc...), not the technical details such as the bus being I2C
compatible or only SMBus.

I have the feeling that we should go on implementing these classes
first, and see what else is needed only after that.

-- 
Jean "Khali" Delvare
http://khali.linux-fr.org/

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-21 20:33         ` Jean Delvare
@ 2004-09-21 21:02           ` Jon Smirl
  -1 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Jean Delvare; +Cc: Michael Hunold, Greg KH, LM Sensors, linux-kernel

This is the special wake code for older monitors.  ATI supplied it and
it is in the radeon driver.

My understanding that this is a generic problem with old DDC monitors
so the code should be in a DDC I2C driver instead of being added to
all of the video drivers. I don't want the DDC driver to decode the
EDID data, it just needs to handle this problem.

I can say that even my current monitors don't always return the EDID
data without being woken up. The only way to see this is to have
multiple video cards in your PC. The secondary cards won't be reset by
the kernel. Reseting the card will run the BIOS which wakes the
monitors up. If you try to get the EDID from the secondary cards
before they are reset you won't be able to reliably read it.

int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
u8 **out_edid)
{
	u32 reg = rinfo->i2c[conn-1].ddc_reg;
	u8 *edid = NULL;
	int i, j;

	OUTREG(reg, INREG(reg) & 
			~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));

	OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
	(void)INREG(reg);

	for (i = 0; i < 3; i++) {
		/* For some old monitors we need the
		 * following process to initialize/stop DDC
		 */
		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
		(void)INREG(reg);
		msleep(13);

		OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
		(void)INREG(reg);
		for (j = 0; j < 5; j++) {
			msleep(10);
			if (INREG(reg) & VGA_DDC_CLK_INPUT)
				break;
		}
		if (j = 5)
			continue;

		OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN);
		(void)INREG(reg);
		msleep(15);
		OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN);
		(void)INREG(reg);
		msleep(15);
		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
		(void)INREG(reg);
		msleep(15);

		/* Do the real work */
		edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]);

		OUTREG(reg, INREG(reg) | 
				(VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
		(void)INREG(reg);
		msleep(15);
		
		OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
		(void)INREG(reg);
		for (j = 0; j < 10; j++) {
			msleep(10);
			if (INREG(reg) & VGA_DDC_CLK_INPUT)
				break;
		}

		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
		(void)INREG(reg);
		msleep(15);
		OUTREG(reg, INREG(reg) |
				(VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
		(void)INREG(reg);
		if (edid)
			break;
	}
	if (out_edid)
		*out_edid = edid;
	if (!edid) {
		RTRACE("radeonfb: I2C (port %d) ... not found\n", conn);
		return MT_NONE;
	}
	if (edid[0x14] & 0x80) {
		/* Fix detection using BIOS tables */
		if (rinfo->is_mobility /*&& conn = ddc_dvi*/ &&
		    (INREG(LVDS_GEN_CNTL) & LVDS_ON)) {
			RTRACE("radeonfb: I2C (port %d) ... found LVDS panel\n", conn);
			return MT_LCD;
		} else {
			RTRACE("radeonfb: I2C (port %d) ... found TMDS panel\n", conn);
			return MT_DFP;
		}
	}
       	RTRACE("radeonfb: I2C (port %d) ... found CRT display\n", conn);
	return MT_CRT;
}

-- 
Jon Smirl
jonsmirl@gmail.com

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-21 18:05         ` Michael Hunold
@ 2004-09-22  8:56           ` Adrian Cox
  -1 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Michael Hunold
  Cc: Jon Smirl, Greg KH, Michael Hunold, Linux Kernel Mailing List,
	Andrew Morton, Linus Torvalds, sensors

On Tue, 2004-09-21 at 19:05, Michael Hunold wrote:

> With that addition, it's possible for the i2c core to check if the 
> .class entries of the adapter and the client match. If they don't then 
> there is no need to probe a driver. This will help to keep non-i2c 
> drivers to be probed on dvb i2c busses (and screw them up accidently). 
> Currently it's up to the driver to decide wheter to probe a bus or not.

I've said it before, but:
This is all the wrong way round. I2C probing is a solution for the
problem of finding sensors on a pre-ACPI PC. We'd never have invented it
if all we had was DVB cards and monitor detection. 

These .class entries are workarounds that shouldn't be required. For DVB
cards, TV capture cards, monitor detection, and embedded systems the
required behaviour is normally known in advance. Why should the top
level driver have to use these workarounds to steer the result of
probing when it already has all the information?

My rough proposal would be:
1) One by one, disable probing on these I2C adapters.

2) In the pci probe function of the DVB or capture card, do a sequence
like this:
my_dev_priv->i2c_adapter = i2c_adapter_create(...);
my_dev_priv->tea6415 = tea6415_create(my_dev_priv->i2c_adapter,
                                      &my_tea6415_parameters);
my_dev_priv->saa7111 = saa7111_create(my_dev_priv->i2c_adapter);

3) Then to use the i2c client:
tea6415_switch(my_dev_priv->tea6415, &vm);

This is type safe, it allows out of tree DVB and capture drivers, and it
never ever sends an unexpected event down an I2C bus. It doesn't even
need to change the I2C core very much.

- Adrian Cox
Humboldt Solutions Ltd.


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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 12:08             ` Jean Delvare
@ 2004-09-22 11:54               ` Adrian Cox
  -1 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Linux Kernel Mailing List, sensors; +Cc: Michael Hunold, Jon Smirl, Greg KH

On Wed, 2004-09-22 at 13:08, Jean Delvare wrote:
> On Wed, 22 Sep 2004 09:56:06 +0100, Adrian Cox wrote

> > These .class entries are workarounds that shouldn't be required. For 
> > DVB cards, TV capture cards, monitor detection, and embedded systems 
> > the required behaviour is normally known in advance. Why should the top
> > level driver have to use these workarounds to steer the result of
> > probing when it already has all the information?
> 
> Well, I don't quite follow you here. On the one hand you agree that sensors
> and video/embedded stuff should be handled differently, but then you don't
> want us to tag them according to their function in order to actually behave
> differently.

I don't want them tagged because I don't want them to ever appear on a
system-wide list. They're an internal detail of a particular card, and
don't even need to be in sysfs. The only reason to have any shared I2C
code at all for these cards is to avoid duplicating the implementation
of bit-banging.

> > 2) In the pci probe function of the DVB or capture card, do a 
> > sequence like this: my_dev_priv->i2c_adapter = 
> > i2c_adapter_create(...); my_dev_priv->tea6415 = 
> > tea6415_create(my_dev_priv->i2c_adapter,                             
> >          &my_tea6415_parameters); my_dev_priv->saa7111 = 
> > saa7111_create(my_dev_priv->i2c_adapter);
> > 
> > 3) Then to use the i2c client:
> > tea6415_switch(my_dev_priv->tea6415, &vm);
> 
> As far as I know, this is exactly what video folks already do. The whole issue
> is not with video folks probing adapters, but with them not wanting us (the
> sensors clients) to arbitrarily probe their video i2c busses in search of
> hardware monitoring chips. Michael's proposal is meant to give us a way not to
> do this anymore.

Not in the current Linux DVB code. A frontend driver registers itself
onto a list, and whenever a DVB card registers its I2C adapter the
available frontends are probed. My solution would throw away all the
list handling in dvb_i2c.c entirely.

> All in all I don't see how we can solve the problem without either a "do not
> probe" flag in the adapter structure or a class bitfield in both the adapter
> and the client structures. I would be fine with either option unless someone
> explains how one is better than the other in any particular case.

What I want is a way for a card driver to create a private I2C adapter,
and private instances of I2C clients, for purposes of code reuse. The
card driver would be responsible for attaching those clients to the bus
and cleaning up the objects on removal. The bus wouldn't be visible in
sysfs, or accessible from user-mode.

Some USB webcams have internal I2C busses to connect the sensor to the
USB chip. The drivers for these ignore the I2C core completely, and
invent their own system for reading and writing the sensor registers.
Maybe that's actually the best way of dealing with this.

- Adrian Cox
Humboldt Solutions Ltd.


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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22  8:56           ` Adrian Cox
@ 2004-09-22 12:08             ` Jean Delvare
  -1 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox, Michael Hunold
  Cc: Jon Smirl, Greg KH, Linux Kernel Mailing List, sensors

On Wed, 22 Sep 2004 09:56:06 +0100, Adrian Cox wrote
> On Tue, 2004-09-21 at 19:05, Michael Hunold wrote:
> 
> > With that addition, it's possible for the i2c core to check if the
> > .class entries of the adapter and the client match. If they don't then
> > there is no need to probe a driver. This will help to keep non-i2c
> > drivers to be probed on dvb i2c busses (and screw them up accidently).
> > Currently it's up to the driver to decide wheter to probe a bus or not.
> 
> I've said it before, but:
> This is all the wrong way round. I2C probing is a solution for the
> problem of finding sensors on a pre-ACPI PC. We'd never have 
> invented it if all we had was DVB cards and monitor detection.

Agreed, the sensors case is different from the other I2C bus users. However I
don't get the "pre-ACPI PC" part. Detecting the hardware monitoring chip is
still needed even in ACPI-enabled PCs. I've almost never seen the ACPI
subsystem handle hardware monitoring (except on my laptop where it presents a
single temperature value and no limits). Instead, the hardware monitoring
chips are still there sitting on the I2C or ISA bus, waiting for us to probe
them. I'm not familiar with ACPI, but if it is supposed to handle hardware
monitoring, it looks like at least the current BIOS and/or Linux
implementations don't handle it yet.

> These .class entries are workarounds that shouldn't be required. For 
> DVB cards, TV capture cards, monitor detection, and embedded systems 
> the required behaviour is normally known in advance. Why should the top
> level driver have to use these workarounds to steer the result of
> probing when it already has all the information?

Well, I don't quite follow you here. On the one hand you agree that sensors
and video/embedded stuff should be handled differently, but then you don't
want us to tag them according to their function in order to actually behave
differently.

Of course we could limit the difference to a simple "do probe or do not probe"
flag. This would probably be sufficent. While we are at it though, clearly
labeling adapters with a class promises a wider usability. Another superiority
with the classes is that the check is done by the core instead of relying on
the client's good will. OK, the client could lie on its class(es) to bypass
the check, but this is quite different from simply omitting to check the "do
not probe" flag and less likely to happen by accident too.

> My rough proposal would be:
> 1) One by one, disable probing on these I2C adapters.

The clients are probing the adapters, not the other way around, so there is no
way to "disable probing on these I2C adapters". The only way is to tag the
adapters as "do not probe" and have either the core or the clients respect
this, just as I described above.

> 2) In the pci probe function of the DVB or capture card, do a 
> sequence like this: my_dev_priv->i2c_adapter = 
> i2c_adapter_create(...); my_dev_priv->tea6415 = 
> tea6415_create(my_dev_priv->i2c_adapter,                             
>          &my_tea6415_parameters); my_dev_priv->saa7111 = 
> saa7111_create(my_dev_priv->i2c_adapter);
> 
> 3) Then to use the i2c client:
> tea6415_switch(my_dev_priv->tea6415, &vm);

As far as I know, this is exactly what video folks already do. The whole issue
is not with video folks probing adapters, but with them not wanting us (the
sensors clients) to arbitrarily probe their video i2c busses in search of
hardware monitoring chips. Michael's proposal is meant to give us a way not to
do this anymore.

> This is type safe, it allows out of tree DVB and capture drivers,
>  and it never ever sends an unexpected event down an I2C bus. It 
> doesn't even need to change the I2C core very much.

The change in the i2c-core will be really simple (comparing two bitfields
isn't that hard), although I agree it'll almost certainly cause troube in the
early days if .class fields are not properly filled in some adapters or clients.

All in all I don't see how we can solve the problem without either a "do not
probe" flag in the adapter structure or a class bitfield in both the adapter
and the client structures. I would be fine with either option unless someone
explains how one is better than the other in any particular case.

Thanks.

-- 
Jean Delvare
http://khali.linux-fr.org/

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 13:38                 ` Jean Delvare
@ 2004-09-22 13:13                   ` Adrian Cox
  -1 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Linux Kernel Mailing List, sensors; +Cc: Michael Hunold, Jon Smirl, Greg KH

On Wed, 2004-09-22 at 14:38, Jean Delvare wrote:
> On Wed, 22 Sep 2004 12:54:08 +0100, Adrian Cox wrote

> > What I want is a way for a card driver to create a private I2C 
> > adapter, and private instances of I2C clients, for purposes of code 
> > reuse. The card driver would be responsible for attaching those 
> > clients to the bus and cleaning up the objects on removal. The bus 
> > wouldn't be visible in sysfs, or accessible from user-mode.
> 
> Aha, this is an interesting point (which was missing from your previous
> explanation). The base of your proposal would be to have several small i2c
> "trees" (where a tree is a list of adapters and a list of clients) instead of
> a larger, unique one. This would indeed solve a number of problems, and I
> admit that it is somehow equivalent to Michael's classes in that it
> efficiently prevents the hardware monitoring clients from probing the video
> stuff. The rest is just details internal to each "tree". As I understand it,
> each video device would be a tree on itself, while the whole hardware
> monitoring stuff would constitute one (bigger) tree. Correct?

Yes. It took me an extra cup of coffee to explain the idea. 

An important detail is that frontends would no longer contain
module_init() and module_exit() functions. Instead, the card driver
would call a function in the frontend module to attach the frontend
client to the tree and simultaneously set the correct parameters for
that specific card. This provides type safety, and a guarantee that the
client parameters match the correct card when mixing cards from
different manufacturers.

> > Some USB webcams have internal I2C busses to connect the sensor to 
> > the USB chip. The drivers for these ignore the I2C core completely, and
> > invent their own system for reading and writing the sensor registers.
> > Maybe that's actually the best way of dealing with this.
> 
> With your proposal, these drivers could use the common code again while still
> being completely separated from the other i2c busses, right?

Possibly, though they tend to have very limited I2C controllers which
makes it more awkward.

- Adrian Cox
Humboldt Solutions Ltd.


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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 11:54               ` Adrian Cox
@ 2004-09-22 13:38                 ` Jean Delvare
  -1 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Adrian Cox, Linux Kernel Mailing List, sensors
  Cc: Michael Hunold, Jon Smirl, Greg KH

On Wed, 22 Sep 2004 12:54:08 +0100, Adrian Cox wrote
> On Wed, 2004-09-22 at 13:08, Jean Delvare wrote:
> > Well, I don't quite follow you here. On the one hand you agree that
> > sensors and video/embedded stuff should be handled differently, but
> > then you don't want us to tag them according to their function in order
> > to actually behave differently.
> 
> I don't want them tagged because I don't want them to ever appear on 
> a system-wide list. They're an internal detail of a particular card, 
> and don't even need to be in sysfs. The only reason to have any 
> shared I2C code at all for these cards is to avoid duplicating the
> implementation of bit-banging.
> (...)
> What I want is a way for a card driver to create a private I2C 
> adapter, and private instances of I2C clients, for purposes of code 
> reuse. The card driver would be responsible for attaching those 
> clients to the bus and cleaning up the objects on removal. The bus 
> wouldn't be visible in sysfs, or accessible from user-mode.

Aha, this is an interesting point (which was missing from your previous
explanation). The base of your proposal would be to have several small i2c
"trees" (where a tree is a list of adapters and a list of clients) instead of
a larger, unique one. This would indeed solve a number of problems, and I
admit that it is somehow equivalent to Michael's classes in that it
efficiently prevents the hardware monitoring clients from probing the video
stuff. The rest is just details internal to each "tree". As I understand it,
each video device would be a tree on itself, while the whole hardware
monitoring stuff would constitute one (bigger) tree. Correct?

> Some USB webcams have internal I2C busses to connect the sensor to 
> the USB chip. The drivers for these ignore the I2C core completely, and
> invent their own system for reading and writing the sensor registers.
> Maybe that's actually the best way of dealing with this.

With your proposal, these drivers could use the common code again while still
being completely separated from the other i2c busses, right?

Thanks.

-- 
Jean Delvare
http://khali.linux-fr.org/

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

* [PATCH][2.6] Add command function to struct i2c_adapter
  2004-09-22 13:38                 ` Jean Delvare
@ 2004-09-22 15:40                   ` Jon Smirl
  -1 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2005-05-19  6:25 UTC (permalink / raw)
  To: Linux Kernel Mailing List, sensors; +Cc: Adrian Cox, Michael Hunold, Greg KH

On Wed, 22 Sep 2004 14:38:46 +0100, Jean Delvare <khali@linux-fr.org> wrote:
> Aha, this is an interesting point (which was missing from your previous
> explanation). The base of your proposal would be to have several small i2c
> "trees" (where a tree is a list of adapters and a list of clients) instead of
> a larger, unique one. This would indeed solve a number of problems, and I
> admit that it is somehow equivalent to Michael's classes in that it
> efficiently prevents the hardware monitoring clients from probing the video
> stuff. The rest is just details internal to each "tree". As I understand it,
> each video device would be a tree on itself, while the whole hardware
> monitoring stuff would constitute one (bigger) tree. Correct?

Any DDC solution needs to leave the data visible in sysfs and
accessible from user space. I'm trying to move the EDID parsing code
out of the kernel.

-- 
Jon Smirl
jonsmirl@gmail.com

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-10-01 23:41               ` Greg KH
  0 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2004-10-01 23:41 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Michael Hunold, linux-kernel, sensors

On Fri, Oct 01, 2004 at 01:22:45PM +0100, Adrian Cox wrote:
> On Fri, 2004-10-01 at 07:52, Greg KH wrote:
> > On Fri, Sep 24, 2004 at 10:21:08PM +0200, Michael Hunold wrote:
> 
> > > If we have a PCI card where we exactly know what we are doing, we can 
> > > use the NO_PROBE flag to effectively block any probing and can use the 
> > > proposed interface to manually connect the clients.
> > 
> > But why?  The .class feature can accomplish this too.  Just create a new
> > class for this type of adapter and device.  Then only that device will
> > be able to be connected to that adapter, just like you want to have
> > happen, right?
> 
> Either the i2c devices need to be able to support a list of permitted
> adapters, or the i2c adapters need a list of permitted clients. A single
> class isn't adequate. Consider the following scenario:
> 
> The FooTV123 has multiplexor MX3R0K3 and frontend XYZZY, the TVMatic3000
> has frontend XYZZY and multiplexor MX31337, and the FooTV124 has
> multiplexor MX31337 and frontend FR012. All three cards are installed in
> the same machine. In the worst case the probe code for MX31337 puts
> MX3R0K3 into a state that requires a hard reset.
> 
> Manual connection of clients makes it easier to develop a driver outside
> the kernel tree, then merge it when ready, without having to allocate a
> number from a central authority.

Ok, I now understand better, thanks for putting up with me :)

So, got a patch to do this?

thanks,

greg k-h

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-10-01 13:57               ` Jean Delvare
  0 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2004-10-01 13:57 UTC (permalink / raw)
  To: Adrian Cox, Greg KH; +Cc: Michael Hunold, linux-kernel, sensors

On Fri, 01 Oct 2004 13:22:45 +0100, Adrian Cox wrote
> Either the i2c devices need to be able to support a list of permitted
> adapters, or the i2c adapters need a list of permitted clients. A single
> class isn't adequate. Consider the following scenario:
> 
> The FooTV123 has multiplexor MX3R0K3 and frontend XYZZY, the TVMatic3000
> has frontend XYZZY and multiplexor MX31337, and the FooTV124 has
> multiplexor MX31337 and frontend FR012. All three cards are 
> installed in the same machine. In the worst case the probe code for 
> MX31337 puts MX3R0K3 into a state that requires a hard reset.
> 
> Manual connection of clients makes it easier to develop a driver outside
> the kernel tree, then merge it when ready, without having to 
> allocate a number from a central authority.

Agreed. Greg's proposal would somehow mean one class per video device adapter,
which doesn't sound good. We have room for only 32 classes anyway. However, I
agree with Greg that a "no probe" flag isn't needed if we already have
well-defined classes.

Basically, probing is something only hardware monitoring chip drivers do (+
eeprom, so we can include the DDC world). Video clients don't probe as far as
I know (because probing just doesn't work here). So, if we were to have a "no
probe" flag, it would always be clear when class is VIDEO and always set when
class is HWMON (I voluntarily simplify, there are a couple more classes), so
it means that the "no probe" flag is redundant. To put it short, simply not
declaring an adapter as class HWMON means it won't be probed ever (the eeprom
case is to be considered separately and may require a class of its own).

> Creating the adapter with a list of permitted clients is also an
> adequate solution for a bus like I2C which doesn't properly support
> probing. The OCP bus on PowerPC has no explicit probing, and uses a
> similar approach of creating the bus with a list of the devices possible
> for that PowerPC model.

This may be fine for the PPC world, but in the i386 world it wont work. To
give you an idea, the MBM database has 1155 motherboards listed, most of which
have hardware monitoring chips on-board. It happens quite often that I don't
find motherboard models I am looking for therein, so a complete base would
have maybe 1500 or 2000 entries. We certainly don't want to have such a base
in the linux kernel tree. It would be unmaintainable, and also would ensure
that new hardware has no chance to work until us developers know about it.
Probing is the way to go there, even if the I2C bus was obviously not designed
for this.

So I2C bus probing won't go away. Classes or flags are what we need (unless we
go for separated I2C adapter lists, but that's a completely different
approach, and obviously we are not interested until someone comes with a solid
patch that really does this.) A working classes system is really next door,
Michael did most of the work already, half of which is already merged into the
kernel tree.

Thanks.

-- 
Jean Delvare
http://khali.linux-fr.org/


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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-10-01 12:22             ` Adrian Cox
  0 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2004-10-01 12:22 UTC (permalink / raw)
  To: Greg KH; +Cc: Michael Hunold, linux-kernel, sensors

On Fri, 2004-10-01 at 07:52, Greg KH wrote:
> On Fri, Sep 24, 2004 at 10:21:08PM +0200, Michael Hunold wrote:

> > If we have a PCI card where we exactly know what we are doing, we can 
> > use the NO_PROBE flag to effectively block any probing and can use the 
> > proposed interface to manually connect the clients.
> 
> But why?  The .class feature can accomplish this too.  Just create a new
> class for this type of adapter and device.  Then only that device will
> be able to be connected to that adapter, just like you want to have
> happen, right?

Either the i2c devices need to be able to support a list of permitted
adapters, or the i2c adapters need a list of permitted clients. A single
class isn't adequate. Consider the following scenario:

The FooTV123 has multiplexor MX3R0K3 and frontend XYZZY, the TVMatic3000
has frontend XYZZY and multiplexor MX31337, and the FooTV124 has
multiplexor MX31337 and frontend FR012. All three cards are installed in
the same machine. In the worst case the probe code for MX31337 puts
MX3R0K3 into a state that requires a hard reset.

Manual connection of clients makes it easier to develop a driver outside
the kernel tree, then merge it when ready, without having to allocate a
number from a central authority.

Creating the adapter with a list of permitted clients is also an
adequate solution for a bus like I2C which doesn't properly support
probing. The OCP bus on PowerPC has no explicit probing, and uses a
similar approach of creating the bus with a list of the devices possible
for that PowerPC model.

- Adrian Cox
Humboldt Solutions Ltd.



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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-10-01  6:52           ` Greg KH
  0 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2004-10-01  6:52 UTC (permalink / raw)
  To: Michael Hunold; +Cc: linux-kernel, sensors

On Fri, Sep 24, 2004 at 10:21:08PM +0200, Michael Hunold wrote:
> >Also, how does this proposal interact with the work on the i2c classes?
> >Although the classes carry more information than a simple flag or a
> >complete separation, both were/may be introduced to achieve the same
> >goal, isn't it?
> 
> Partly, yes.
> 
> The .class approach is necessary to have a finer grained access control 
> by the i2c-core regarding bus classes, ie. not the client drivers have 
> to check if the bus should be probed (for example dcc drivers on a dvb 
> bus). This is useful in general.
> 
> If we have a PCI card where we exactly know what we are doing, we can 
> use the NO_PROBE flag to effectively block any probing and can use the 
> proposed interface to manually connect the clients.

But why?  The .class feature can accomplish this too.  Just create a new
class for this type of adapter and device.  Then only that device will
be able to be connected to that adapter, just like you want to have
happen, right?

thanks,

greg k-h

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-24 20:21         ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-24 20:21 UTC (permalink / raw)
  To: linux-kernel, sensors; +Cc: Greg KH

Hi,

On 24.09.2004 20:05, Jean Delvare wrote:
>>We like to have an completly isolated i2c adapter, where the device 
>>driver can invite i2c drivers to connect an i2c client to. When the 
>>connection is made, an "interface" pointer with client-specific data
>>or function pointers can be provided.
>>(...)
>>- add a new NO_PROBE flag to struct i2c_adapter, so a particular
>>adapter is never probed by anyone

> I don't get it. If the adapter is isolated, there is no way the i2c-core
> will probe it anyway. As Adrian Cox underlined, it should be far easier
> and more efficient to separate these adapters from the main i2c adapters
> list from the beginning than leaving them in the main list and then try
> and prevent future probings using a flag.

There a two scenarios, where you don't have full control over the i2c 
adapter or you don't want to fully isolate the bus:

1) Some dvb drivers are bttv-sub-drivers, ie. bttv does the pci and i2c 
handling by itself. You have the struct i2c_adapter pointer, but it has 
been registered by bttv, most likely as an analog and/or digital tv i2c bus.

2) Embedded platforms have usually a system-wide i2c bus, so you cannot 
isolate the bus here.

It's useful to register both adapters and drivers to the i2c-core, so 
you keep the door open.

> Also, how does this proposal interact with the work on the i2c classes?
> Although the classes carry more information than a simple flag or a
> complete separation, both were/may be introduced to achieve the same
> goal, isn't it?

Partly, yes.

The .class approach is necessary to have a finer grained access control 
by the i2c-core regarding bus classes, ie. not the client drivers have 
to check if the bus should be probed (for example dcc drivers on a dvb 
bus). This is useful in general.

If we have a PCI card where we exactly know what we are doing, we can 
use the NO_PROBE flag to effectively block any probing and can use the 
proposed interface to manually connect the clients.

> Thanks,

CU
Michael.

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-24 18:05       ` Jean Delvare
  0 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2004-09-24 18:05 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Greg KH, linux-kernel, sensors

> We like to have an completly isolated i2c adapter, where the device 
> driver can invite i2c drivers to connect an i2c client to. When the 
> connection is made, an "interface" pointer with client-specific data
> or function pointers can be provided.
> (...)
> - add a new NO_PROBE flag to struct i2c_adapter, so a particular
> adapter is never probed by anyone

I don't get it. If the adapter is isolated, there is no way the i2c-core
will probe it anyway. As Adrian Cox underlined, it should be far easier
and more efficient to separate these adapters from the main i2c adapters
list from the beginning than leaving them in the main list and then try
and prevent future probings using a flag.

Also, how does this proposal interact with the work on the i2c classes?
Although the classes carry more information than a simple flag or a
complete separation, both were/may be introduced to achieve the same
goal, isn't it?

Thanks,

-- 
Jean "Khali" Delvare
http://khali.linux-fr.org/

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-24 17:06     ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-24 17:06 UTC (permalink / raw)
  To: Greg KH; +Cc: Michael Hunold, Linux Kernel Mailing List, sensors

Hi,

On 21.09.2004 17:41, Greg KH wrote:
> On Mon, Sep 20, 2004 at 07:19:24PM +0200, Michael Hunold wrote:
> 
>> 
>>+	/* a ioctl like command that can be used to perform specific functions
>>+	 * with the adapter.
>>+	 */
>>+	int (*command)(struct i2c_adapter *adapter, unsigned int cmd, void *arg);
> 
> 
> Ick ick ick.  We don't like ioctls for the very reason they aren't type
> safe, and you can pretty much stick anything in there you want.  So
> let's not try to add the same type of interface to another subsystem.

Ok, Gerd Knorr and I have been discussing this and we have come up with 
the following idea.

We like to have an completly isolated i2c adapter, where the device 
driver can invite i2c drivers to connect an i2c client to. When the 
connection is made, an "interface" pointer with client-specific data or 
function pointers can be provided.

- i2c adapter and i2c clients register themselves as usual

- add a new NO_PROBE flag to struct i2c_adapter, so a particular adapter 
is never probed by anyone

- add these two functions to struct i2c_driver:
int (*connect)(struct i2c_adapter *adapter, void *interface, struct 
i2c_client **client);
int (*disconnect)(struct i2c_client *client);

- add new generic i2c functions:
struct i2c_driver* i2c_driver_get(char *name);
void i2c_driver_put(struct i2c_driver *drv);

- the dvb-ttpci driver now can do the following:

struct stv0299_interface {
	struct dvb_adapter *dvb_adap;
	int tuner_addr;
};

struct stv0299_interface s_if;
struct i2c_driver *drv;
struct i2c_client *clt;

request_module("stv0299");
drv = i2c_driver_get("stv0299");
// fill s_if here
drv->connect(adap, &s_if, &clt);

Now inside the "connect" function of the stv0299 demodulator i2c driver 
the device is probed, registered to the adapter and the pointer to the 
interface with the h/w dependend information is stored.

> thanks,
> greg k-h

The crucial point is probably the void * interface pointer, isn't it? Is 
this a no-no in this situation?

The dvb-ttpci driver is inviting a very specific driver, no probing 
involved. The driver interface is well-defined and will only be hidden 
behind the void * pointer to avoid a functional reference to the 
demodulator driver.

We have discussed simply adding a type-safe stv0299-specific connect 
function as well, but that would introduce a functional dependency. The 
dvb-ttpci driver can be used with about 8 different frontend drivers, so 
loading the driver would cause unnecessary frontend drivers to be loaded 
as well.

CU
Michael.

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-23 20:18                   ` Adrian Cox
  0 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2004-09-23 20:18 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Linux Kernel Mailing List, sensors, Jon Smirl, Greg KH

On Thu, 2004-09-23 at 08:09, Michael Hunold wrote:
> We need to keep in mind, that the adapter interface must be a per-client 
> interface. On PCI devices it's simple: you have a i2c bus bound to a dvb 
> card and know which chipsets can be there. The bus is dvb specific.
> 
> On embedded platforms, however, you usually have one one i2c bus, where 
> everything is present: dvb frontends, audio/video multiplexers, 
> digital/analog audio converters, stuff like that.
> 
> So if you create *the* i2c bus and invite i2c client to participate at 
> the party, you need to provide different interfaces to the different 
> chipsets.

I may have to solve a similar problem when connecting an image sensor
directly to an embedded processor. My current idea looks a bit like
this:

1) The I2C bus is a platform device, created at boot time, independent
of my video capture module.
2) My module contains a dummy I2C driver, which exists solely to grab an
i2c_adapter pointer for the platform I2C device.

My underlying libraries don't have to worry whether the i2c_adapter came
from a parent PCI device or a platform device. My only worry is that
power management may still provide us with a headache, as we'll have to
cope with platform devices being suspended in any order.

- Adrian Cox
Humboldt Solutions Ltd.



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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-23  7:48                     ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-23  7:48 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Jon Smirl, Greg KH

Hi,

On 22.09.2004 20:32, Adrian Cox wrote:
>>Aha, this is an interesting point (which was missing from your previous
>>explanation). The base of your proposal would be to have several small i2c
>>"trees" (where a tree is a list of adapters and a list of clients) instead of
>>a larger, unique one. This would indeed solve a number of problems, and I
>>admit that it is somehow equivalent to Michael's classes in that it
>>efficiently prevents the hardware monitoring clients from probing the video
>>stuff. The rest is just details internal to each "tree". As I understand it,
>>each video device would be a tree on itself, while the whole hardware
>>monitoring stuff would constitute one (bigger) tree. Correct?

> I've been rereading the code, and it could be even simpler. How about
> this:
> 
> 1) The card driver defines an i2c_adapter structure, but never calls
> i2c_add_adapter(). The only extra thing it needs to do is to initialise
> the semaphores in the structure.
> 2) The frontend calls i2c_transfer() directly.
> 3) The i2c core never gets involved, and there is never any i2c_client
> structure.
> 
> This gives us the required reuse of the I2C algo-bit code, without any
> of the list walking or device probing being required.

This is the way the linux-dvb guys are currently favouring.

In some cases there should be an adapter that has been registered with 
i2c_add_adapter() because there can always be other drivers (audio/video 
multiplexes and the like) that you cannot get your hands on because they 
are provided by the manufacturer of some embedded platform.

For some cards (mostly bt8x8 based, ie. the core parts are driven by the 
"bttv" driver) and hybrid cards (ie. dvb cards that have a separate 
analog video input) the common i2c bus cannot go away, but it should be 
protected by proper .class entries in both the clients and adapters.

We think about splitting the frontend drivers into library parts, ie. 
library functions for demodulators (the current frontend drivers) and 
h/w dependent plls (or tuners).

Because of the fact the pci device knows which devices are present on 
the bus, it can register and configure the demod, pll and other specific 
dvb devices with direct i2c_transfer()s directly. If there are multiple 
combinations possible, it can use the library to probe as well.

The question we are currently facing is: are the frontend or demod i2c 
drivers real and independent i2c clients like thermal sensors or are 
they part of a h/w dependent design that should better be configured on 
a library basis?

If they are independend, then we need i2c bus types and type-safe 
client<=>adapter communication to exchange configuration and control 
informations, because the ioctl interface currently works from the 
adapter to the client and is not type safe.
Another question is, if this is probably too bloated. Think of simple 
matrix switch chipsets: the only "interface" they have is "set input a 
to output b".

> - Adrian Cox
> Humboldt Solutions Ltd.

CU
Michael.

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-23  7:41                     ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-23  7:41 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Jon Smirl, Greg KH

Hi,

On 22.09.2004 20:32, Adrian Cox wrote:
>>Aha, this is an interesting point (which was missing from your previous
>>explanation). The base of your proposal would be to have several small i2c
>>"trees" (where a tree is a list of adapters and a list of clients) instead of
>>a larger, unique one. This would indeed solve a number of problems, and I
>>admit that it is somehow equivalent to Michael's classes in that it
>>efficiently prevents the hardware monitoring clients from probing the video
>>stuff. The rest is just details internal to each "tree". As I understand it,
>>each video device would be a tree on itself, while the whole hardware
>>monitoring stuff would constitute one (bigger) tree. Correct?

> I've been rereading the code, and it could be even simpler. How about
> this:
> 
> 1) The card driver defines an i2c_adapter structure, but never calls
> i2c_add_adapter(). The only extra thing it needs to do is to initialise
> the semaphores in the structure.
> 2) The frontend calls i2c_transfer() directly.
> 3) The i2c core never gets involved, and there is never any i2c_client
> structure.
> 
> This gives us the required reuse of the I2C algo-bit code, without any
> of the list walking or device probing being required.

This is the way the linux-dvb guys are currently favouring.

In some cases there should be an adapter that has been registered with 
i2c_add_adapter() because there can always be other drivers (audio/video 
multiplexes and the like) that you cannot get your hands on because they 
are provided by the manufacturer of some embedded platform.

For some cards (mostly bt8x8 based, ie. the core parts are driven by the 
"bttv" driver) and hybrid cards (ie. dvb cards that have a separate 
analog video input) the common i2c bus cannot go away, but it should be 
protected by proper .class entries in both the clients and adapters.

We think about splitting the frontend drivers into library parts, ie. 
library functions for demodulators (the current frontend drivers) and 
h/w dependent plls (or tuners).

Because of the fact the pci device knows which devices are present on 
the bus, it can register and configure the demod, pll and other specific 
dvb devices with direct i2c_transfer()s directly. If there are multiple 
combinations possible, it can use the library to probe as well.

The question we are currently facing is: are the frontend or demod i2c 
drivers real and independent i2c clients like thermal sensors or are 
they part of a h/w dependent design that should better be configured on 
a library basis?

If they are independend, then we need i2c bus types and type-safe 
client<=>adapter communication to exchange configuration and control 
informations, because the ioctl interface currently works from the 
adapter to the client and is not type safe.
Another question is, if this is probably too bloated. Think of simple 
matrix switch chipsets: the only "interface" they have is "set input a 
to output b".

> - Adrian Cox
> Humboldt Solutions Ltd.

CU
Michael.

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-23  7:09                 ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-23  7:09 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Jon Smirl, Greg KH

Hi,

On 22.09.2004 13:54, Adrian Cox wrote:
> Not in the current Linux DVB code. A frontend driver registers itself
> onto a list, and whenever a DVB card registers its I2C adapter the
> available frontends are probed. My solution would throw away all the
> list handling in dvb_i2c.c entirely.

Kernels including 2.6.9-rc2-mm1 have the proprietary dvb_i2c 
implementation inside, ie. no kernel i2c at all. I have recently sent a 
patch to Andrew that converts all dvb drivers and frontends to fully use 
kernel i2c. The current discussion is completely about the 
not-yet-officially-released dvb subsystem using kernel-i2c.

>>All in all I don't see how we can solve the problem without either a "do not
>>probe" flag in the adapter structure or a class bitfield in both the adapter
>>and the client structures. I would be fine with either option unless someone
>>explains how one is better than the other in any particular case.

> What I want is a way for a card driver to create a private I2C adapter,
> and private instances of I2C clients, for purposes of code reuse. The
> card driver would be responsible for attaching those clients to the bus
> and cleaning up the objects on removal. The bus wouldn't be visible in
> sysfs, or accessible from user-mode.

We're having a similar discussion on the linux-dvb mailing list and I 
have made a similar suggestion. There shouldn't be such a thing as a 
generic i2c bus at all - at least not for specific PCI or AGP cards 
having an i2c bus, because you really now what's there.

The adapters should be able to create a specific i2c bus. This bus then 
should have a well-defined client<->adapter interface. The adapter 
provides an interface clients can use for example to query h/w dependent 
informations, like "Is it possible to have chipset XY on your bus?". For 
DVB this question can be answered using pci subvendor/subdevice 
informations. This avoids the need to add a command() function to struct 
i2c_adapter.

If the adapter wants a client to join the bus and the client is really 
found, then the client must provide a well-defined set of functions as 
well. The adapter can then control the device in a type-safe manner and 
doesn't have to control it using the current ioctl interface.

> - Adrian Cox
> Humboldt Solutions Ltd.

We need to keep in mind, that the adapter interface must be a per-client 
interface. On PCI devices it's simple: you have a i2c bus bound to a dvb 
card and know which chipsets can be there. The bus is dvb specific.

On embedded platforms, however, you usually have one one i2c bus, where 
everything is present: dvb frontends, audio/video multiplexers, 
digital/analog audio converters, stuff like that.

So if you create *the* i2c bus and invite i2c client to participate at 
the party, you need to provide different interfaces to the different 
chipsets.

CU
Michael.

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 20:04                     ` Mark M. Hoffman
  0 siblings, 0 replies; 76+ messages in thread
From: Mark M. Hoffman @ 2004-09-22 20:04 UTC (permalink / raw)
  To: Adrian Cox
  Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Jon Smirl, Greg KH

Hi Adrian:

* Adrian Cox <adrian@humboldt.co.uk> [2004-09-22 19:32:31 +0100]:
> On Wed, 2004-09-22 at 14:38, Jean Delvare wrote:
> 
> > Aha, this is an interesting point (which was missing from your previous
> > explanation). The base of your proposal would be to have several small i2c
> > "trees" (where a tree is a list of adapters and a list of clients) instead of
> > a larger, unique one. This would indeed solve a number of problems, and I
> > admit that it is somehow equivalent to Michael's classes in that it
> > efficiently prevents the hardware monitoring clients from probing the video
> > stuff. The rest is just details internal to each "tree". As I understand it,
> > each video device would be a tree on itself, while the whole hardware
> > monitoring stuff would constitute one (bigger) tree. Correct?
> 
> I've been rereading the code, and it could be even simpler. How about
> this:
> 
> 1) The card driver defines an i2c_adapter structure, but never calls
> i2c_add_adapter(). The only extra thing it needs to do is to initialise
> the semaphores in the structure.
> 2) The frontend calls i2c_transfer() directly.
> 3) The i2c core never gets involved, and there is never any i2c_client
> structure.

Yes, almost...

Why force your card driver to re-implement i2c_smbus_read_byte() and all
its relatives?  Go ahead and define the i2c_client structure(s) as well,
but don't i2c_attach_client().  Sensors drivers do their probing before
attaching the client, so I know that works.

> This gives us the required reuse of the I2C algo-bit code, without any
> of the list walking or device probing being required.

Ditto, *plus* you can still reuse all the i2c_core helper routines that
require a client structure.

Regards,

-- 
Mark M. Hoffman
mhoffman@lightlink.com


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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 18:55                           ` Jean Delvare
  0 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2004-09-22 18:55 UTC (permalink / raw)
  To: Adrian Cox
  Cc: Jon Smirl, Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

> > For my purpose of decoding the EDID read only access is fine. 
> > 
> > But I do know there are programs that use the user space I2C drivers
> > to control extended monitor functions. Some monitors let you set
> > brightnesss, contrast, on/off via the I2C link.
> 
> In which case you will need the current mechanism, with the class
> mechanism to stop sensor drivers probing the bus.

There is no absolute necessity to do that as far as I can see. Usually,
there is nothing on the DDC bus but the DDC EEPROM itself, so the probes
won't happen except for the EEPROM itself, for which it is safe.

-- 
Jean "Khali" Delvare
http://khali.linux-fr.org/

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 18:32                   ` Adrian Cox
  0 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2004-09-22 18:32 UTC (permalink / raw)
  To: Linux Kernel Mailing List, sensors; +Cc: Michael Hunold, Jon Smirl, Greg KH

On Wed, 2004-09-22 at 14:38, Jean Delvare wrote:

> Aha, this is an interesting point (which was missing from your previous
> explanation). The base of your proposal would be to have several small i2c
> "trees" (where a tree is a list of adapters and a list of clients) instead of
> a larger, unique one. This would indeed solve a number of problems, and I
> admit that it is somehow equivalent to Michael's classes in that it
> efficiently prevents the hardware monitoring clients from probing the video
> stuff. The rest is just details internal to each "tree". As I understand it,
> each video device would be a tree on itself, while the whole hardware
> monitoring stuff would constitute one (bigger) tree. Correct?

I've been rereading the code, and it could be even simpler. How about
this:

1) The card driver defines an i2c_adapter structure, but never calls
i2c_add_adapter(). The only extra thing it needs to do is to initialise
the semaphores in the structure.
2) The frontend calls i2c_transfer() directly.
3) The i2c core never gets involved, and there is never any i2c_client
structure.

This gives us the required reuse of the I2C algo-bit code, without any
of the list walking or device probing being required.

- Adrian Cox
Humboldt Solutions Ltd.



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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 17:17                           ` Jon Smirl
  0 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2004-09-22 17:17 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

Can this code be implemented in the current framework? Don't I need
the attach/detach_adapter hook which I can't get to from the algo_bit
code?

http://lkml.org/lkml/2004/9/21/181

-- 
Jon Smirl
jonsmirl@gmail.com

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 16:51                         ` Adrian Cox
  0 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2004-09-22 16:51 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

On Wed, 2004-09-22 at 17:07, Jon Smirl wrote:
> On Wed, 22 Sep 2004 16:56:19 +0100, Adrian Cox <adrian@humboldt.co.uk> wrote:
> > Would it do for a display device to expose read-only EDID data through
> > sysfs, or do you need I2C level access to DDC from userspace?
> 
> For my purpose of decoding the EDID read only access is fine. 
> 
> But I do know there are programs that use the user space I2C drivers
> to control extended monitor functions. Some monitors let you set
> brightnesss, contrast, on/off via the I2C link.

In which case you will need the current mechanism, with the class
mechanism to stop sensor drivers probing the bus.

- Adrian Cox
Humboldt Solutions Ltd.



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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 16:07                       ` Jon Smirl
  0 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2004-09-22 16:07 UTC (permalink / raw)
  To: Adrian Cox; +Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

On Wed, 22 Sep 2004 16:56:19 +0100, Adrian Cox <adrian@humboldt.co.uk> wrote:
> Would it do for a display device to expose read-only EDID data through
> sysfs, or do you need I2C level access to DDC from userspace?

For my purpose of decoding the EDID read only access is fine. 

But I do know there are programs that use the user space I2C drivers
to control extended monitor functions. Some monitors let you set
brightnesss, contrast, on/off via the I2C link.

-- 
Jon Smirl
jonsmirl@gmail.com

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 15:56                     ` Adrian Cox
  0 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2004-09-22 15:56 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Linux Kernel Mailing List, sensors, Michael Hunold, Greg KH

On Wed, 2004-09-22 at 16:40, Jon Smirl wrote:

> Any DDC solution needs to leave the data visible in sysfs and
> accessible from user space. I'm trying to move the EDID parsing code
> out of the kernel.

Would it do for a display device to expose read-only EDID data through
sysfs, or do you need I2C level access to DDC from userspace?

- Adrian Cox
Humboldt Solutions Ltd.



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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 15:40                   ` Jon Smirl
  0 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2004-09-22 15:40 UTC (permalink / raw)
  To: Linux Kernel Mailing List, sensors; +Cc: Adrian Cox, Michael Hunold, Greg KH

On Wed, 22 Sep 2004 14:38:46 +0100, Jean Delvare <khali@linux-fr.org> wrote:
> Aha, this is an interesting point (which was missing from your previous
> explanation). The base of your proposal would be to have several small i2c
> "trees" (where a tree is a list of adapters and a list of clients) instead of
> a larger, unique one. This would indeed solve a number of problems, and I
> admit that it is somehow equivalent to Michael's classes in that it
> efficiently prevents the hardware monitoring clients from probing the video
> stuff. The rest is just details internal to each "tree". As I understand it,
> each video device would be a tree on itself, while the whole hardware
> monitoring stuff would constitute one (bigger) tree. Correct?

Any DDC solution needs to leave the data visible in sysfs and
accessible from user space. I'm trying to move the EDID parsing code
out of the kernel.

-- 
Jon Smirl
jonsmirl@gmail.com

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 13:38                 ` Jean Delvare
  0 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2004-09-22 13:38 UTC (permalink / raw)
  To: Adrian Cox, Linux Kernel Mailing List, sensors
  Cc: Michael Hunold, Jon Smirl, Greg KH

On Wed, 22 Sep 2004 12:54:08 +0100, Adrian Cox wrote
> On Wed, 2004-09-22 at 13:08, Jean Delvare wrote:
> > Well, I don't quite follow you here. On the one hand you agree that
> > sensors and video/embedded stuff should be handled differently, but
> > then you don't want us to tag them according to their function in order
> > to actually behave differently.
> 
> I don't want them tagged because I don't want them to ever appear on 
> a system-wide list. They're an internal detail of a particular card, 
> and don't even need to be in sysfs. The only reason to have any 
> shared I2C code at all for these cards is to avoid duplicating the
> implementation of bit-banging.
> (...)
> What I want is a way for a card driver to create a private I2C 
> adapter, and private instances of I2C clients, for purposes of code 
> reuse. The card driver would be responsible for attaching those 
> clients to the bus and cleaning up the objects on removal. The bus 
> wouldn't be visible in sysfs, or accessible from user-mode.

Aha, this is an interesting point (which was missing from your previous
explanation). The base of your proposal would be to have several small i2c
"trees" (where a tree is a list of adapters and a list of clients) instead of
a larger, unique one. This would indeed solve a number of problems, and I
admit that it is somehow equivalent to Michael's classes in that it
efficiently prevents the hardware monitoring clients from probing the video
stuff. The rest is just details internal to each "tree". As I understand it,
each video device would be a tree on itself, while the whole hardware
monitoring stuff would constitute one (bigger) tree. Correct?

> Some USB webcams have internal I2C busses to connect the sensor to 
> the USB chip. The drivers for these ignore the I2C core completely, and
> invent their own system for reading and writing the sensor registers.
> Maybe that's actually the best way of dealing with this.

With your proposal, these drivers could use the common code again while still
being completely separated from the other i2c busses, right?

Thanks.

-- 
Jean Delvare
http://khali.linux-fr.org/


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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 13:13                   ` Adrian Cox
  0 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2004-09-22 13:13 UTC (permalink / raw)
  To: Linux Kernel Mailing List, sensors; +Cc: Michael Hunold, Jon Smirl, Greg KH

On Wed, 2004-09-22 at 14:38, Jean Delvare wrote:
> On Wed, 22 Sep 2004 12:54:08 +0100, Adrian Cox wrote

> > What I want is a way for a card driver to create a private I2C 
> > adapter, and private instances of I2C clients, for purposes of code 
> > reuse. The card driver would be responsible for attaching those 
> > clients to the bus and cleaning up the objects on removal. The bus 
> > wouldn't be visible in sysfs, or accessible from user-mode.
> 
> Aha, this is an interesting point (which was missing from your previous
> explanation). The base of your proposal would be to have several small i2c
> "trees" (where a tree is a list of adapters and a list of clients) instead of
> a larger, unique one. This would indeed solve a number of problems, and I
> admit that it is somehow equivalent to Michael's classes in that it
> efficiently prevents the hardware monitoring clients from probing the video
> stuff. The rest is just details internal to each "tree". As I understand it,
> each video device would be a tree on itself, while the whole hardware
> monitoring stuff would constitute one (bigger) tree. Correct?

Yes. It took me an extra cup of coffee to explain the idea. 

An important detail is that frontends would no longer contain
module_init() and module_exit() functions. Instead, the card driver
would call a function in the frontend module to attach the frontend
client to the tree and simultaneously set the correct parameters for
that specific card. This provides type safety, and a guarantee that the
client parameters match the correct card when mixing cards from
different manufacturers.

> > Some USB webcams have internal I2C busses to connect the sensor to 
> > the USB chip. The drivers for these ignore the I2C core completely, and
> > invent their own system for reading and writing the sensor registers.
> > Maybe that's actually the best way of dealing with this.
> 
> With your proposal, these drivers could use the common code again while still
> being completely separated from the other i2c busses, right?

Possibly, though they tend to have very limited I2C controllers which
makes it more awkward.

- Adrian Cox
Humboldt Solutions Ltd.



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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 12:08             ` Jean Delvare
  0 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2004-09-22 12:08 UTC (permalink / raw)
  To: Adrian Cox, Michael Hunold
  Cc: Jon Smirl, Greg KH, Linux Kernel Mailing List, sensors

On Wed, 22 Sep 2004 09:56:06 +0100, Adrian Cox wrote
> On Tue, 2004-09-21 at 19:05, Michael Hunold wrote:
> 
> > With that addition, it's possible for the i2c core to check if the
> > .class entries of the adapter and the client match. If they don't then
> > there is no need to probe a driver. This will help to keep non-i2c
> > drivers to be probed on dvb i2c busses (and screw them up accidently).
> > Currently it's up to the driver to decide wheter to probe a bus or not.
> 
> I've said it before, but:
> This is all the wrong way round. I2C probing is a solution for the
> problem of finding sensors on a pre-ACPI PC. We'd never have 
> invented it if all we had was DVB cards and monitor detection.

Agreed, the sensors case is different from the other I2C bus users. However I
don't get the "pre-ACPI PC" part. Detecting the hardware monitoring chip is
still needed even in ACPI-enabled PCs. I've almost never seen the ACPI
subsystem handle hardware monitoring (except on my laptop where it presents a
single temperature value and no limits). Instead, the hardware monitoring
chips are still there sitting on the I2C or ISA bus, waiting for us to probe
them. I'm not familiar with ACPI, but if it is supposed to handle hardware
monitoring, it looks like at least the current BIOS and/or Linux
implementations don't handle it yet.

> These .class entries are workarounds that shouldn't be required. For 
> DVB cards, TV capture cards, monitor detection, and embedded systems 
> the required behaviour is normally known in advance. Why should the top
> level driver have to use these workarounds to steer the result of
> probing when it already has all the information?

Well, I don't quite follow you here. On the one hand you agree that sensors
and video/embedded stuff should be handled differently, but then you don't
want us to tag them according to their function in order to actually behave
differently.

Of course we could limit the difference to a simple "do probe or do not probe"
flag. This would probably be sufficent. While we are at it though, clearly
labeling adapters with a class promises a wider usability. Another superiority
with the classes is that the check is done by the core instead of relying on
the client's good will. OK, the client could lie on its class(es) to bypass
the check, but this is quite different from simply omitting to check the "do
not probe" flag and less likely to happen by accident too.

> My rough proposal would be:
> 1) One by one, disable probing on these I2C adapters.

The clients are probing the adapters, not the other way around, so there is no
way to "disable probing on these I2C adapters". The only way is to tag the
adapters as "do not probe" and have either the core or the clients respect
this, just as I described above.

> 2) In the pci probe function of the DVB or capture card, do a 
> sequence like this: my_dev_priv->i2c_adapter = 
> i2c_adapter_create(...); my_dev_priv->tea6415 = 
> tea6415_create(my_dev_priv->i2c_adapter,                             
>          &my_tea6415_parameters); my_dev_priv->saa7111 = 
> saa7111_create(my_dev_priv->i2c_adapter);
> 
> 3) Then to use the i2c client:
> tea6415_switch(my_dev_priv->tea6415, &vm);

As far as I know, this is exactly what video folks already do. The whole issue
is not with video folks probing adapters, but with them not wanting us (the
sensors clients) to arbitrarily probe their video i2c busses in search of
hardware monitoring chips. Michael's proposal is meant to give us a way not to
do this anymore.

> This is type safe, it allows out of tree DVB and capture drivers,
>  and it never ever sends an unexpected event down an I2C bus. It 
> doesn't even need to change the I2C core very much.

The change in the i2c-core will be really simple (comparing two bitfields
isn't that hard), although I agree it'll almost certainly cause troube in the
early days if .class fields are not properly filled in some adapters or clients.

All in all I don't see how we can solve the problem without either a "do not
probe" flag in the adapter structure or a class bitfield in both the adapter
and the client structures. I would be fine with either option unless someone
explains how one is better than the other in any particular case.

Thanks.

-- 
Jean Delvare
http://khali.linux-fr.org/


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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22 11:54               ` Adrian Cox
  0 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2004-09-22 11:54 UTC (permalink / raw)
  To: Linux Kernel Mailing List, sensors; +Cc: Michael Hunold, Jon Smirl, Greg KH

On Wed, 2004-09-22 at 13:08, Jean Delvare wrote:
> On Wed, 22 Sep 2004 09:56:06 +0100, Adrian Cox wrote

> > These .class entries are workarounds that shouldn't be required. For 
> > DVB cards, TV capture cards, monitor detection, and embedded systems 
> > the required behaviour is normally known in advance. Why should the top
> > level driver have to use these workarounds to steer the result of
> > probing when it already has all the information?
> 
> Well, I don't quite follow you here. On the one hand you agree that sensors
> and video/embedded stuff should be handled differently, but then you don't
> want us to tag them according to their function in order to actually behave
> differently.

I don't want them tagged because I don't want them to ever appear on a
system-wide list. They're an internal detail of a particular card, and
don't even need to be in sysfs. The only reason to have any shared I2C
code at all for these cards is to avoid duplicating the implementation
of bit-banging.

> > 2) In the pci probe function of the DVB or capture card, do a 
> > sequence like this: my_dev_priv->i2c_adapter = 
> > i2c_adapter_create(...); my_dev_priv->tea6415 = 
> > tea6415_create(my_dev_priv->i2c_adapter,                             
> >          &my_tea6415_parameters); my_dev_priv->saa7111 = 
> > saa7111_create(my_dev_priv->i2c_adapter);
> > 
> > 3) Then to use the i2c client:
> > tea6415_switch(my_dev_priv->tea6415, &vm);
> 
> As far as I know, this is exactly what video folks already do. The whole issue
> is not with video folks probing adapters, but with them not wanting us (the
> sensors clients) to arbitrarily probe their video i2c busses in search of
> hardware monitoring chips. Michael's proposal is meant to give us a way not to
> do this anymore.

Not in the current Linux DVB code. A frontend driver registers itself
onto a list, and whenever a DVB card registers its I2C adapter the
available frontends are probed. My solution would throw away all the
list handling in dvb_i2c.c entirely.

> All in all I don't see how we can solve the problem without either a "do not
> probe" flag in the adapter structure or a class bitfield in both the adapter
> and the client structures. I would be fine with either option unless someone
> explains how one is better than the other in any particular case.

What I want is a way for a card driver to create a private I2C adapter,
and private instances of I2C clients, for purposes of code reuse. The
card driver would be responsible for attaching those clients to the bus
and cleaning up the objects on removal. The bus wouldn't be visible in
sysfs, or accessible from user-mode.

Some USB webcams have internal I2C busses to connect the sensor to the
USB chip. The drivers for these ignore the I2C core completely, and
invent their own system for reading and writing the sensor registers.
Maybe that's actually the best way of dealing with this.

- Adrian Cox
Humboldt Solutions Ltd.



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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-22  8:56           ` Adrian Cox
  0 siblings, 0 replies; 76+ messages in thread
From: Adrian Cox @ 2004-09-22  8:56 UTC (permalink / raw)
  To: Michael Hunold
  Cc: Jon Smirl, Greg KH, Michael Hunold, Linux Kernel Mailing List,
	Andrew Morton, Linus Torvalds, sensors

On Tue, 2004-09-21 at 19:05, Michael Hunold wrote:

> With that addition, it's possible for the i2c core to check if the 
> .class entries of the adapter and the client match. If they don't then 
> there is no need to probe a driver. This will help to keep non-i2c 
> drivers to be probed on dvb i2c busses (and screw them up accidently). 
> Currently it's up to the driver to decide wheter to probe a bus or not.

I've said it before, but:
This is all the wrong way round. I2C probing is a solution for the
problem of finding sensors on a pre-ACPI PC. We'd never have invented it
if all we had was DVB cards and monitor detection. 

These .class entries are workarounds that shouldn't be required. For DVB
cards, TV capture cards, monitor detection, and embedded systems the
required behaviour is normally known in advance. Why should the top
level driver have to use these workarounds to steer the result of
probing when it already has all the information?

My rough proposal would be:
1) One by one, disable probing on these I2C adapters.

2) In the pci probe function of the DVB or capture card, do a sequence
like this:
my_dev_priv->i2c_adapter = i2c_adapter_create(...);
my_dev_priv->tea6415 = tea6415_create(my_dev_priv->i2c_adapter,
                                      &my_tea6415_parameters);
my_dev_priv->saa7111 = saa7111_create(my_dev_priv->i2c_adapter);

3) Then to use the i2c client:
tea6415_switch(my_dev_priv->tea6415, &vm);

This is type safe, it allows out of tree DVB and capture drivers, and it
never ever sends an unexpected event down an I2C bus. It doesn't even
need to change the I2C core very much.

- Adrian Cox
Humboldt Solutions Ltd.



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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-21 21:02           ` Jon Smirl
  0 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2004-09-21 21:02 UTC (permalink / raw)
  To: Jean Delvare; +Cc: Michael Hunold, Greg KH, LM Sensors, linux-kernel

This is the special wake code for older monitors.  ATI supplied it and
it is in the radeon driver.

My understanding that this is a generic problem with old DDC monitors
so the code should be in a DDC I2C driver instead of being added to
all of the video drivers. I don't want the DDC driver to decode the
EDID data, it just needs to handle this problem.

I can say that even my current monitors don't always return the EDID
data without being woken up. The only way to see this is to have
multiple video cards in your PC. The secondary cards won't be reset by
the kernel. Reseting the card will run the BIOS which wakes the
monitors up. If you try to get the EDID from the secondary cards
before they are reset you won't be able to reliably read it.

int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
u8 **out_edid)
{
	u32 reg = rinfo->i2c[conn-1].ddc_reg;
	u8 *edid = NULL;
	int i, j;

	OUTREG(reg, INREG(reg) & 
			~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));

	OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
	(void)INREG(reg);

	for (i = 0; i < 3; i++) {
		/* For some old monitors we need the
		 * following process to initialize/stop DDC
		 */
		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
		(void)INREG(reg);
		msleep(13);

		OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
		(void)INREG(reg);
		for (j = 0; j < 5; j++) {
			msleep(10);
			if (INREG(reg) & VGA_DDC_CLK_INPUT)
				break;
		}
		if (j == 5)
			continue;

		OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN);
		(void)INREG(reg);
		msleep(15);
		OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN);
		(void)INREG(reg);
		msleep(15);
		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
		(void)INREG(reg);
		msleep(15);

		/* Do the real work */
		edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]);

		OUTREG(reg, INREG(reg) | 
				(VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
		(void)INREG(reg);
		msleep(15);
		
		OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
		(void)INREG(reg);
		for (j = 0; j < 10; j++) {
			msleep(10);
			if (INREG(reg) & VGA_DDC_CLK_INPUT)
				break;
		}

		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
		(void)INREG(reg);
		msleep(15);
		OUTREG(reg, INREG(reg) |
				(VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
		(void)INREG(reg);
		if (edid)
			break;
	}
	if (out_edid)
		*out_edid = edid;
	if (!edid) {
		RTRACE("radeonfb: I2C (port %d) ... not found\n", conn);
		return MT_NONE;
	}
	if (edid[0x14] & 0x80) {
		/* Fix detection using BIOS tables */
		if (rinfo->is_mobility /*&& conn == ddc_dvi*/ &&
		    (INREG(LVDS_GEN_CNTL) & LVDS_ON)) {
			RTRACE("radeonfb: I2C (port %d) ... found LVDS panel\n", conn);
			return MT_LCD;
		} else {
			RTRACE("radeonfb: I2C (port %d) ... found TMDS panel\n", conn);
			return MT_DFP;
		}
	}
       	RTRACE("radeonfb: I2C (port %d) ... found CRT display\n", conn);
	return MT_CRT;
}

-- 
Jon Smirl
jonsmirl@gmail.com

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-21 20:33         ` Jean Delvare
  0 siblings, 0 replies; 76+ messages in thread
From: Jean Delvare @ 2004-09-21 20:33 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Michael Hunold, Greg KH, linux-kernel, sensors

> There is a related I2C problem with EEPROMs and DDC monitors. DDC
> monitors look just like EEPROMs, the EEPROM driver can even read most
> of them. But there are DDC monitors that need special wakeup sequences
> before their ROMs will appear.
> 
> EEPROM and DDC are both algo_bit clients.

Not true. algo-bit refers to i2c bus implementations, not i2c clients.
It happens that all DDC monitors are accessed through bit-banging I2C
busses (real I2C busses, as opposed to SMBus), but other EEPROMs do not.
Most EEPROMs are from memory modules and hang off the motherboard SMBus
(which by definition does not depend on algo-bit).

> When you attach a bus to algo_bit both clients will run.

FYI, there is no ddcmon driver in Linux 2.6 and I believe there won't
be. The eeprom driver should do the job. Converting the EEPROM data to
significant info belongs to user-space.

> There is concern that sending the
> special DDC wake up sequence down non-DDC buses might mess up the bus.

This is however true, and I agree that Michael's proposal could help in
this respect. And I actually believe that his I2C classes implementation
would help more than the "command" callback. After all, you need the DDC
data to identify the monitor, and (in some cases) need to know the
monitor to properly access the DDC data...

(BTW, I am not certain at all that we should add support for these
broken monitors. As far as I can see, they do not support the DDC
standard, too bad for them. I would hate to break standard-compliant
monitors by implementing tricks to support non-standard ones.)

> A proposal was made to implement different classes of algo_bit clients
> but this was never implemented. Would a class solution help with the
> dvb problem too?

As a side note, the classes apply to all I2C adapters, not just
bit-banging ones. And classes apply to the busses purposes (video, ddc,
sensors etc...), not the technical details such as the bus being I2C
compatible or only SMBus.

I have the feeling that we should go on implementing these classes
first, and see what else is needed only after that.

-- 
Jean "Khali" Delvare
http://khali.linux-fr.org/

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-21 18:05         ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-21 18:05 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Greg KH, Michael Hunold, Linux Kernel Mailing List,
	Andrew Morton, Linus Torvalds, sensors

Hi,

On 21.09.2004 19:39, Jon Smirl wrote:
> There is a related I2C problem with EEPROMs and DDC monitors. DDC
> monitors look just like EEPROMs, the EEPROM driver can even read most
> of them. But there are DDC monitors that need special wakeup sequences
> before their ROMs will appear.
> 
> EEPROM and DDC are both algo_bit clients. When you attach a bus to
> algo_bit both clients will run. There is concern that sending the
> special DDC wake up sequence down non-DDC buses might mess up the bus.
> 
> A proposal was made to implement different classes of algo_bit clients
> but this was never implemented. Would a class solution help with the
> dvb problem too?

It would help to separate dvb clients and dvb busses. I just posted 
another mail titled "Adding .class field to struct i2c_client (was Re: 
[PATCH][2.6] Add command function to struct i2c_adapter" that adds a 
.class entry to the struct i2c_client.

With that addition, it's possible for the i2c core to check if the 
.class entries of the adapter and the client match. If they don't then 
there is no need to probe a driver. This will help to keep non-i2c 
drivers to be probed on dvb i2c busses (and screw them up accidently). 
Currently it's up to the driver to decide wheter to probe a bus or not.

CU
Michael.


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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-21 17:39       ` Jon Smirl
  0 siblings, 0 replies; 76+ messages in thread
From: Jon Smirl @ 2004-09-21 17:39 UTC (permalink / raw)
  To: Michael Hunold
  Cc: Greg KH, Michael Hunold, Linux Kernel Mailing List,
	Andrew Morton, Linus Torvalds, sensors

There is a related I2C problem with EEPROMs and DDC monitors. DDC
monitors look just like EEPROMs, the EEPROM driver can even read most
of them. But there are DDC monitors that need special wakeup sequences
before their ROMs will appear.

EEPROM and DDC are both algo_bit clients. When you attach a bus to
algo_bit both clients will run. There is concern that sending the
special DDC wake up sequence down non-DDC buses might mess up the bus.

A proposal was made to implement different classes of algo_bit clients
but this was never implemented. Would a class solution help with the
dvb problem too?


-- 
Jon Smirl
jonsmirl@gmail.com

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-21 17:10     ` Michael Hunold
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Hunold @ 2004-09-21 17:10 UTC (permalink / raw)
  To: Greg KH
  Cc: Michael Hunold, Linux Kernel Mailing List, Andrew Morton,
	Linus Torvalds, sensors

Hi,

On 21.09.2004 17:41, Greg KH wrote:
> On Mon, Sep 20, 2004 at 07:19:24PM +0200, Michael Hunold wrote:
> 
>> 
>>+	/* a ioctl like command that can be used to perform specific functions
>>+	 * with the adapter.
>>+	 */
>>+	int (*command)(struct i2c_adapter *adapter, unsigned int cmd, void *arg);

> Ick ick ick.  We don't like ioctls for the very reason they aren't type
> safe, and you can pretty much stick anything in there you want.  So
> let's not try to add the same type of interface to another subsystem.

Ok.

> How about we add the exact explicit functionality that you want, one
> function per "type" of operation, like all other subsystems have.

Hm, but the functionality depends heavily on the types of clients and 
adapters.

For the dvb subsystem, for example, if we know that the i2c adapter is 
some sort of dvb device, we might need to set the pll from the frontend 
i2c client if the user wants to tune to some frequency. The pll settings 
are very h/w specific, so they should be in the driver implementing the 
i2c adapter. So from the dvb frontend dvb i2c client we would call 
adapter->command(adapter, DVB_FE_SET_PLL, &arg).

You don't mean to add a int(*dvb_fe_set_pll)(...) function to the struct 
i2c_adapter instead, don't you?

Isn't this is a general problem? Isn't there the need to have some 
abstraction to allow message passing between i2c clients and i2c 
adapters in both ways, because i2c clients are never that independend 
from the i2c adapter and have always some h/w dependend parts inside?

> thanks,
> greg k-h

Regards
Michael.

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

* Re: [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-21 15:41   ` Greg KH
  0 siblings, 0 replies; 76+ messages in thread
From: Greg KH @ 2004-09-21 15:41 UTC (permalink / raw)
  To: Michael Hunold
  Cc: Linux Kernel Mailing List, Andrew Morton, Linus Torvalds, sensors

On Mon, Sep 20, 2004 at 07:19:24PM +0200, Michael Hunold wrote:
>  
> +	/* a ioctl like command that can be used to perform specific functions
> +	 * with the adapter.
> +	 */
> +	int (*command)(struct i2c_adapter *adapter, unsigned int cmd, void *arg);

Ick ick ick.  We don't like ioctls for the very reason they aren't type
safe, and you can pretty much stick anything in there you want.  So
let's not try to add the same type of interface to another subsystem.

How about we add the exact explicit functionality that you want, one
function per "type" of operation, like all other subsystems have.

thanks,

greg k-h

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

* [PATCH][2.6] Add command function to struct i2c_adapter
@ 2004-09-20 17:19 Michael Hunold
  2004-09-21 15:41   ` Greg KH
  0 siblings, 1 reply; 76+ messages in thread
From: Michael Hunold @ 2004-09-20 17:19 UTC (permalink / raw)
  To: Linux Kernel Mailing List; +Cc: Greg KH, Andrew Morton, Linus Torvalds

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

Hi there,

the attached patch adds a command function to struct i2c_adapter, 
similar to the command function that is already there for struct i2c_client.

The reason behind this is as follows:
In the DVB subsystem, the tuners are accessed via normal kernel i2c 
drivers. One big problem is, that tuners can be wired very differently 
depending on the surrounding hardware. Currently, we need to keep 
specific settings which are unique to a hardware design in the 
independent i2c tuner driver. This is both very ugly and makes it 
impossible to support DVB drivers which are not in the official Linux 
kernel tree, but could otherwise use in-kernel frontend driver.

If the struct i2c_adapter has a command function, it would be possible 
to get additional informations from the adapter in the i2c client's 
attach_adapter() function *before* probing the device and guessing 
things like i2c addresses or other hardware settings.

This patch is non-intrusive. It doesn't affect any current drivers, but 
only future developments.

Are there any objections against this patch?

Regards
Michael.

[-- Attachment #2: i2c-add-command.diff --]
[-- Type: text/plain, Size: 633 bytes --]

diff -ura linux-2.6.9-rc2-mm1/include/linux/i2c.h b/include/linux/i2c.h
--- linux-2.6.9-rc2-mm1/include/linux/i2c.h	2004-09-20 12:38:24.000000000 +0200
+++ b/include/linux/i2c.h	2004-09-20 18:53:32.000000000 +0200
@@ -231,6 +231,11 @@
 	struct i2c_algorithm *algo;/* the algorithm to access the bus	*/
 	void *algo_data;
 
+	/* a ioctl like command that can be used to perform specific functions
+	 * with the adapter.
+	 */
+	int (*command)(struct i2c_adapter *adapter, unsigned int cmd, void *arg);
+
 	/* --- administration stuff. */
 	int (*client_register)(struct i2c_client *);
 	int (*client_unregister)(struct i2c_client *);

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

end of thread, other threads:[~2005-05-19  6:25 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-19  6:25 [Fwd: [PATCH][2.6] Add command function to struct i2c_adapter] Michael Hunold
2004-09-21 13:28 ` [PATCH][2.6] Add command function to struct i2c_adapter Jean Delvare
2005-05-19  6:25   ` Jean Delvare
2004-09-21 14:38   ` Michael Hunold
2005-05-19  6:25     ` Michael Hunold
2004-09-21 17:41   ` Adding .class field to struct i2c_client (was " Michael Hunold
2005-05-19  6:25     ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add Michael Hunold
2004-09-21 20:16     ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter Jon Smirl
2005-05-19  6:25       ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Jon Smirl
2004-09-24  0:02     ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter Greg KH
2005-05-19  6:25       ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Greg KH
2004-09-24  6:22       ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter Michael Hunold
2005-05-19  6:25         ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Michael Hunold
2004-09-24 16:43         ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Add command function to struct i2c_adapter Greg KH
2005-05-19  6:25           ` Adding .class field to struct i2c_client (was Re: [PATCH][2.6] Greg KH
  -- strict thread matches above, loose matches on Subject: below --
2004-09-20 17:19 [PATCH][2.6] Add command function to struct i2c_adapter Michael Hunold
2005-05-19  6:25 ` Greg KH
2004-09-21 15:41   ` Greg KH
2005-05-19  6:25   ` Michael Hunold
2004-09-21 17:10     ` Michael Hunold
2005-05-19  6:25     ` Jon Smirl
2004-09-21 17:39       ` Jon Smirl
2005-05-19  6:25       ` Michael Hunold
2004-09-21 18:05         ` Michael Hunold
2005-05-19  6:25         ` Adrian Cox
2004-09-22  8:56           ` Adrian Cox
2005-05-19  6:25           ` Jean Delvare
2004-09-22 12:08             ` Jean Delvare
2005-05-19  6:25             ` Adrian Cox
2004-09-22 11:54               ` Adrian Cox
2005-05-19  6:25               ` Jean Delvare
2004-09-22 13:38                 ` Jean Delvare
2005-05-19  6:25                 ` Jon Smirl
2004-09-22 15:40                   ` Jon Smirl
2005-05-19  6:25                   ` Adrian Cox
2004-09-22 15:56                     ` Adrian Cox
2005-05-19  6:25                     ` Jon Smirl
2004-09-22 16:07                       ` Jon Smirl
2005-05-19  6:25                       ` Adrian Cox
2004-09-22 16:51                         ` Adrian Cox
2005-05-19  6:25                         ` Jean Delvare
2004-09-22 18:55                           ` Jean Delvare
2005-05-19  6:25                         ` Jon Smirl
2004-09-22 17:17                           ` Jon Smirl
2005-05-19  6:25                 ` Adrian Cox
2004-09-22 13:13                   ` Adrian Cox
2005-05-19  6:25                 ` Adrian Cox
2004-09-22 18:32                   ` Adrian Cox
2005-05-19  6:25                   ` Mark M. Hoffman
2004-09-22 20:04                     ` Mark M. Hoffman
2005-05-19  6:25                   ` Michael Hunold
2004-09-23  7:48                     ` Michael Hunold
2005-05-19  6:25                   ` Michael Hunold
2004-09-23  7:41                     ` Michael Hunold
2005-05-19  6:25               ` Michael Hunold
2004-09-23  7:09                 ` Michael Hunold
2005-05-19  6:25                 ` Adrian Cox
2004-09-23 20:18                   ` Adrian Cox
2005-05-19  6:25       ` Jean Delvare
2004-09-21 20:33         ` Jean Delvare
2005-05-19  6:25         ` Jon Smirl
2004-09-21 21:02           ` Jon Smirl
2005-05-19  6:25   ` Michael Hunold
2004-09-24 17:06     ` Michael Hunold
2005-05-19  6:25     ` Jean Delvare
2004-09-24 18:05       ` Jean Delvare
2005-05-19  6:25       ` Michael Hunold
2004-09-24 20:21         ` Michael Hunold
2005-05-19  6:25         ` Greg KH
2004-10-01  6:52           ` Greg KH
2005-05-19  6:25           ` Adrian Cox
2004-10-01 12:22             ` Adrian Cox
2005-05-19  6:25             ` Jean Delvare
2004-10-01 13:57               ` Jean Delvare
2005-05-19  6:25             ` Greg KH
2004-10-01 23:41               ` Greg KH

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.