CSI-2 V4L2 driver programming - linux

I am interested in porting a camera driver from one SOC(Pi) to another SOC(Jetson) which both run flavors of linux and have CSI-2 interfaces.
I have the source code for the driver. I'm trying to understand how the CSI-2 interface works with respect to V4L2. The camera is controlled by the SOC through an I2C line which control functions are provided for in the source code. What I am confused about is if I need to write something to actually pull frames from the camera and control the CSI interface directly? Or is that all standardized by the CSI-2 interface and handled by V4L2?
If you wanted to access the raw data from the camera how is this done?

Related

How do I write a network device driver using SPI?

I have implemented a device driver for the NRF24L01+ transceiver in userspace using rust. The userspace driver makes use of the kernel spi interface driver. Writing the driver as kernel module seems incredibly hard, as the documentation for linux/netdevice.h as found in linux device drivers seems outdated (or I'm just not smart enough to understand the intricate details).
A new project from the TU Munich proposes the use of vfio. From my understanding this type of driver implementation uses the iommu to manage isolation to protected memory areas for the devices. "Project Ixy" uses the network device as block device, hence it can be mapped. SPI is different as insofar it is a streaming protocol.
My question is, if it is possible to integrate the user space spi network device driver into the linux network stack, e.g. having all protocols etc handled by the network stack. Is it possible to use a similar approach as Project Ixy, like having a small component in kernel space, which is isolated for security, that builds a "bridge" to userland?
I think it is possible in two ways:
using TAP interface
writing your own "bridging" interface like TAP between user space and kernel space
If ethernet-like interface is enough for you - then use TAP. I mean TAP provides functionality where physical layer is moved to user space. In your case it could work like this: data received by SPI can be pushed to TAP interface to linux network stack. The data received from TAP interface (from Linux network stack) you can push via SPI. Is that what you wanted?
If ethernet-like interace (as TAP is) is not enough for you - you can write your own interface in kernel space basing on TAP sources.

Linux device driver with optional multiple platform driver interfaces

Suppose I have a chip that has multiple options for interfacing with it, for example, the chip may have an I2C interface and a SPI interface and I can choose one of these interfaces and wire the device accordingly. How would I write a linux device driver for such device?
A chip with this behavior is ssd1307, which already has a driver implementation in the mainline linux kernel (https://github.com/torvalds/linux/blob/master/drivers/video/fbdev/ssd1307fb.c), implemented only for its I2C interface (the chip also has a 3/4 Wire SPI Interface). As you can see in the code, the probe function relies heavily on the fact that it is an I2C interface, so in order to use the SPI interface I would need to write an entirely new driver, repeating a lot of common code, or insert a lot of #ifdefs, which don't seem to be good approaches to me.
For chips providing several interface types, standard practice is to provide core driver and interface-specific frontends for it.
Several examples could be found e.g. in sound/soc/codecs/: pcm179x.c / pcm179x-i2c.c / pcm179x-spi.c and others.
This is not (yet?) done for ssd1307.

How do 'clients' fit in with 'platform devices' and 'platform drivers'

Reading about the driver-model platform, my understanding is that a platform driver is a static piece of kernel code that controls a platform device, which is a device which generally is always present in the system, as opposed to a driver composed of a kernel module, which can be loaded or removed at will and controls devices which might not always be connected. This answer seems to support that statement.
If all this is true, I expect it's what I'm looking for. I am trying to write a kernel module which, among other things, needs to communicate with an external device over I2C. While the external device isn't always part of the system, the I2C bus IS, so it ought to be controlled by a platform driver. So rather than writing code in my module to directly control the I2C, I ought to be using the platform driver. I found what I believe to be the proper platform driver for the I2C bus on my platform here, and it does use < linux/platform_device.h >, so that seems to be consistent.
However, in addition to this, when looking up I2C in general, I have seen reference to an I2C "client". From the name alone, this sounds like what I am trying to write now, a kernel module that uses the platform driver to communicate over I2C. However, in the documentation for the driver-model platform, nothing about a "client" is mentioned, so I don't know if this is correct or if it is some completely separate different model.
So how does a "client" kernel module fit into the driver-platform model for interfacing with hardware in Linux? Is my module supposed to instantiate a struct of the i2c_driver, or is that something done by the platform driver, and the module is supposed to create an interface to that?

Hardware ISP and v4l2

I'm new to Linux.
My doubt is regarding v4l2 driver supporting existing ISP harware in Jetson TX1.
I would like to know whether basic v4l2 implementation in Linux provides an interface to send data to ISP(hardware module) or not?
If not provided, is it possible to modify the v4l2 implementation so that it does not bypass ISP.
And also, I would like to know, how the data flows from an image sensor to system memory through v4l2( if possible can i get sources for block diagram representing this data flow)
Please help me...

What can be removed from the Linux i2c-dev driver to serve as a base for a new driver meant for only one device?

I'm trying to write a Linux character device driver for a device that just happens to communicate over I2C. The device is an Atmel microcontroller with code that provides an I2C address. It already works using the typical i2c-dev method on the Linux-side.
So now I want to replicate i2c-dev as a new driver that works specifically with this particular device, so that I can add some of my own device-specific abstraction code on top. But I'd like to trim out all the unnecessary code from i2c-dev that currently makes it generic. What can be removed in this situation?
What can be removed in this situation?
You're actually asking an XY question.
You would be better off looking at and adapting an existing I2C device driver that is already similar in required functionality, rather than hacking a special case driver for userspace access.
So now I want to replicate i2c-dev as a new driver that works specifically with this particular device, so that I can add some of my own device-specific abstraction code on top
So then you actually need to write a "Client driver" as described below (from Linux Documentation/i2c/summary):
When we talk about I2C, we use the following terms:
Bus -> Algorithm
Adapter
Device -> Driver
Client
An Algorithm driver contains general code that can be used for a whole class
of I2C adapters. Each specific adapter driver either depends on one algorithm
driver, or includes its own implementation.
A Driver driver (yes, this sounds ridiculous, sorry) contains the general
code to access some type of device. Each detected device gets its own
data in the Client structure. Usually, Driver and Client are more closely
integrated than Algorithm and Adapter.
Details are in Documentation/i2c/writing-clients.
To find a driver of similar functionality, scan the list of I2C client drivers. Note that these I2C drivers are located in the Linux source tree by their functionality (e.g. drivers/rtc/ or drivers/hwmon/) and not their interface (i.e. I2C).

Resources