Re: Seeking help for getting rid of i2c_clients_command()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/10/19 4:05 PM, Wolfram Sang wrote:
> Hi Hans,
> 
> I know it is 13 years since you wrote that code:
> 
> ba8fc39954bf ("V4L/DVB (4270): Add tda9887-specific tuner configuration")
> 
> There, you added i2c_clients_command() which looks today like this:
> 
> 	i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
> 			    &tda9887_cfg);
> 
> Now, I would like to get rid of the i2c_clients_command() API, and this
> is the one remaining user. While trying to convert it into a local
> function, I started wondering why i2c_clients_command() is used at all.
> Why do we need to try all devices on the bus? A few lines later we have:
> 
> 	tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
> 
> so i2c_props.addr seems to have a valid address? Or are there multiple
> tuners on that bus? Can you kindly shed some light on this?

Oh boy... The tuner code is awful for many reasons.

One reason is that for a given video capture card there can be multiple
tuner devices: Analog TV, Digital TV, Analog demodulator and/or radio.

The TUNER_SET_CONFIG command is (AFAICT) only used to configure the
tda9887 (demodulator), and the problem is that when this code was written
the tuner instance that is calling TUNER_SET_CONFIG does not know on which
i2c address the demod is.

TUNER_SET_CONFIG is called whenever the TV or radio frequency is
changed, and when that happens the demod needs to update its configuration
as well. So the tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); is for the
tuner itself (whose i2c address is known), but i2c_clients_command is
basically broadcasting to anyone on the bus, and only the tda9987 will
actually act on the TUNER_SET_CONFIG command.

However, it looks like this code is only used by hybrid tuners (i.e.
supporting both digital and analog TV), and that the available tuners
are now added to a global list via hybrid_tuner_request_state().

This should make it possible for tuner-simple.c to actually lookup the
i2c address of the demod from that global list and use a direct call.

I've CC-ed a bunch of people who know more about DVB than I do, so
I hope they can double-check that I am on the right track.

Wolfram, do you just want to get rid of i2c_clients_command or the i2c
command() callback as well?

Regardless, it would be nice if we can get rid of the command() callback
in the media subsystem. If I read the code right, then you can get the
tuner struct of an i2c_client using 'struct tuner *t = to_tuner(i2c_get_clientdata(c));'
and from there you can get the analog_demod_ops that you need to
configure the tda9887.

So I think this would work:

1) walk hybrid_tuner_instance_list to find a tuner with name "tda9887" for
   the given i2c_adapter.
2) get the i2c_client from the adapter with address state->i2c_props.addr.
3) struct tuner *t = to_tuner(i2c_get_clientdata(c));
4) if (t->fe.ops.analog_ops.set_config)
	t->fe.ops.analog_ops.set_config(&t->fe, &config);

Regards,

	Hans



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux