Hello Linux Kernel Driver Gurus!
I'm writing a v4l2 driver for a camera that uses a serial interface for configuration. I'd like the driver to configure the camera, as it keeps the client code consistent across camera models. The question is: what's the best way to access the camera's serial interface from the driver module?
From what I hear, accessing files from a kernel driver is a big no-no, but it can be done. As such, I'm currently using the following code snippet, but it feels like a hack.
oldfs = get_fs(); set_fs(KERNEL_DS); fd->f_pos=0; fd->f_op->write(fd, data, data_len, &fd->f_pos); set_fs(oldfs);
My question is really: what's the right way to do this?
I presume that since a serial port is involved, this must be some kind of embedded system. After all, not many PCs even have serial ports. I also assume that the serial port can be considered a permanent connection, at least from the user's perspective. If that is all true, then you don't really want a TTY device. You want to access the device as a private UART.
If you have a look at the Wolfson audio codecs (sound/soc/wm*.c) you will see an example of devices that primarily communicate over I2S but have an auxiliary I2C interface for configuration. This is conceptually what you want, I believe. The driver presents a unified interface to software, and issues commands to whatever hardware is appropriate. Obviously this is much cleaner than having to expose hardware implementation details to userspace.
I couldn't find a good example of a UART driver in the kernel that works this way, but hopefully I've described what to look for. From a practical rather than technical purity point of view, it might just be better to do file I/O from the kernel.
First I would advise you to find a way to do this from the userspace if possible: what you try to achieve here really is userspace code in kernel code.
But if you don't find a way to do it, this article shows you how to do userspace calls in kernelspace.
Since you want to access a serial port, you should have calls that tty oriented, for instance for open:
serial_fd = sys_open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK))