After a couple more days to reflect on what I reported, and design my work-arounds, it is worth sharing the work-arounds I am using now, and a more detailed suggested solution...
Beyond what was reported above, I wanted to be able to use the test video source on, say IPU1/CSI1 while I might have a mipi camera on IPU1/CSI0 or IPU1/CSI1, and our GS2960 on IPU0/CSI0.
What I further discovered is that the module mxc_v4l2_capture is pretty much still written around having one IPU.
For example, the master_attach(...) function checks (the slaves privates) for the desired/expected/designed CSI, but not for the IPU. If I have a mipi camera which wants to attach to IPU1/CSI0, this software might happily try to connect it to IPU0/CSI0 if nothing is already there.
In the current implementation all 4 potential mxc video input sources are all called "Mxc Camera" with nothing to distinguish IPU and CSI... I have implemented a work-around which is detailed below.
I understand the desire not to muck too much with the v4l2 core. This is code shared broadly within Linux and apparently does what is needed well enough.
Instead of changing v4l2_int_device to carry MXC specific data, I think a better platform work-around might be to extend it something like this:
Create an extended structure for v4l2 master and slave devices which attach through the mxc platform:
struct mxc_v4l2_master {
struct v4l2_master v4lmaster;
struct clock* my_master_clock;
int my_master_member;
...etc...
};
struct mxc_v4l2_slave {
struct v4l2_slave v4lsensor;
struct clock* my_sensor_clock;
int my_sensor_member;
...etc...
};
Again, this is only for devices attaching through the IPUx/CSIy inputs on an mxc platform.
Also, I suggest moving away from statically instantiated module data. It's an old idea and fundamentally limited.
My driver data, except for the IOCTL table, is dynamically allocated:
struct my_v4l2_int_device {
struct my_sensor_privates actually_private_data;
struct mxc_v4l_2slave platform_slave_data;
struct v4l2_int_device v4l2dev_data;
};
In this suggestion anything used by mxc_v4l2_capture(etc.) that is in sensor_data would be in struct mxc_v4l_2slave now.
This is a structure both the mxc platform v4l2 driver knows about, but that each added sensor also knows about.
It does not break the basic v4l2 core code, but allows the platform to extend valuable shared information needed by capture driver and sensor driver alike, but not waste space with useless members and preserves driver-private data.
Separately, The work-around I am debugging now is in two parts:
First confronts the complete ambiguity of what v4l2 master device I want to attach to, and this, at least, is mind-numbingly simple:
In init_camera_struct(...) I add the following:
*(cam->video_dev) = mxc_v4l_template;
/* SDA-CCC - Let's name this device a bit more specifically:
** .name = "Mxc Camera" becomes "Mxc[IPU]Camera[CSI]"
*/
cam->video_dev.name[10] = 0; /* Ensure string terminator */
cam->video_dev.name[9] = '0'+csi_id; /* CSI ID after 'Camera' */
cam->video_dev.name[3] = '0'+ipu_id; /* IPU ID after 'Mxc' */
After the template is copied, I name the input specifically to its IPUi/CSIc port as MxciCamerac
Now, in my devices probe(...) function I can populate the v4l2_int_slave.attach_to member with the actual name of the IPUx/CSIy input I have built.
Second works around the need for the mostly useless, to me, struct sensor_data which mxc_v4l2_capture(etc.) depends upon as my device private data:
struct my_v4l2_int_device {
struct sensor_data visible_sensor_privates;
struct my_sensor_privates actually_private_driver_data;
struct v4l2_int_2slave v4l2_slave_data;
struct v4l2_int_device v4l2_device_data;
};
The pointer to this is stored in the v4l2_int_device.priv member, and naturally points to what mxc_v4l2_capture(etc.) seems to need.
I populate what I must, and what I can use of struct sensor_data and put the rest of what I need into struct my_sensor_privates.
Since one device is a platform device, and the other is an SPI device, the I2C stuff in struct sensor_data is totally useless.
My inputs don't have brightnes or contrast controls, so most of that other stuff is also totally useless.
I put the other controls my device actually needs in struct my_sensor_privates.
I populate struct v4l2_int_2slave to specifically attach to the input it is connected to by name, without change to v4l2 core software.
I register struct v4l2_int_device as dynamically allocated instead of static data - so I can have more than one of a thing, if desired.
So, for example, I can replace any actual camera with the internal self-test generator of the CSI by just changing the device tree.
It is just making the best I can of a design which violates the concept of driver-private data, but is well on its way to working.