Simple SPI device driver - linux

I have written a simple driver for a character device in Non Blocking mode using epoll.
Now I would like to use that driver for SPI interface.
What should be the device name or how will I map the actual device with the kernel ?
How will I use the interrupt?
Also who is the Master and Slave?Suppose I am connecting a SPI compatible device to the panda board.Will that device becomes a slave and the development board becomes Master?
I am a newbie.I am using a panda board.
In what way should I go through the Technical Reference manual?
I would really appreciate if anybody would explain and clarify my doubts.

You probably want to connect your driver to a SPI bus driver. This requires a slight reworking of your driver. See drivers/spi/spi.c
You'll be using the commands for the bus (master, the CPU side) to read and write the commands to the unit.
I don't know what a Panda board is, but if it connects via SPI, it might be a master, but it is probably a slave.

Go through the basics of spi here

Related

Add a SPI filter between driver controller and userspace spidev driver on Linux

We have Linux on a product. The customer is free to write its own application and need to use the spidev driver to access a specific peripheral.
This peripheral is accessed through the SPI master driver for Atmel processor (spi-atmel.c).
Now, I would like to control/limit some data and command which can be sent from the userspace (user application) to this particular peripheral.
I need to keep compatibility on user side and then keep the spidev interface so my basic idea would be to add a driver between the spidev and the master SPI controller but I'm not sure if it's the best way and if so how to achieve that correctly, do you have an idea ?
Thank for your help,
Regards

How to transfer data with high speed through USB?

I'm trying to find a way to send/receive data through USB port of an ARM processor on a zynq board (ZC706) running petalinux.
I searched on the net and I'm totally confused where to begin. I found solutions but those did not consider USB to be connected to ARM processor, high-speed data transfer or petalinux.
I know how to write simple linux kernel codes and I know how to work with zynq board.
To be specific, I want to know how to write a piece of code, better to say a library of functions, in petalinux to read and write to usb port connected to ARM as high-speed as possible.
Seems like you are trying to do some quite sophisticated thing.
First I would like to say that USB is not some kind of port which you can read data "byte after byte" like in case of serial or parallel ports.
I would recommend you to start with reading about USB 2.0 and EHCI documentation (it take some time). Additionally you need to know what kind of USB is your board - is it host or device USB type? In case of usb device type - probably you need to write your own driver for this board and connect it to some USB host (PC for example). Then you need to create some communication protocol over USB. Luckily on the PC side you would use the libusb library for this. I mean you need to write program which uses libusb library for communication with your board.
Quite a lot of work to do.

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).

How does the USB storage driver works in Linux?

I am trying to find out a high-level overview of how the USB storage driver works in Linux. I'm looking for a simple article or even a picture/flowchart describing how it works.
Basically, I'm looking to get these questions answered:
When you plug the device into your computer, what happens? Is there a daemon that picks up on it, or does the event trigger an interrupt somewhere? Does the core USB driver read information about the device before passing control over to the USB storage driver? How does it decide what type of device it is? How does the device get mounted, and what allows it to communicate with the computer's filesystem? When I copy a file, what does the data flow look like in the kernel?
I hope the question isn't too vague - I tried Google to no avail, so I'm wondering if anyone knows any articles or diagrams that can explain this, or perhaps if they can explain it themselves without too much effort. Thanks.
No, it is a very good question.
The block writing is going in linux with the block device layer. The filesystems are working with this block dev layer.
If this layer wants to write something out, says it to the driver of the usb master device. This driver is talking with the usb controller chip of the motherboard.
This chip is very simple: the usb is practically a serial port, with a lot of extensions, mainly targeting the autoconfiguration and the power management. But basically, you can write out bytes, and read in bytes.
Your questions:
When you plug the device into your computer, what happens? Is there a daemon that picks up on it, or does the event trigger an interrupt somewhere?
The device (usb slave) says the master (in the motherboard): "I am here". The usb controller chip gets the message and says it to the kernel (normally) with an interrupt. The kernel reinitializes and rescans the usb bus, and says the udev: "here is a new 1234:5678 usb device on the usb tree 1.3.5"
"How does it decide what type of device it is?"
Usb devices have a vendor and model id, and they can say this on ask. Google for "usb ids".
"How does the device get mounted, and what allows it to communicate with the computer's filesystem?"
The kernel only loads the driver and says the udev (which is in userspace): "Here is a new block device on device number 22:16". From this, udev tries to mount this with some userspace daemon, it is already distribution-dependant.

How should I structure a linux driver that uses several chips in one device?

I have a hardware device that consists of 3 separate chips on an I2C bus. I would like to group them together and expose them to userland as one logical device. The user would see the logical device represented by a single directory somewhere in /sys as well as the nodes you'd expect from the I2C chips under /sys/class/i2c-adapter/i2c-?/*.
One of the chips is an MCP23017 which as far as I can tell already has a driver (drivers/gpio/gpio-mcp23s08.c) and I'd like to reuse it. Another of the chips is a PCA9685 and I would like to contribute a driver for this chip that uses the PWM system in include/linux/pwm.h. The third chip is an MCU running custom firmware.
How should I structure the set of drivers? One idea I had is to register a platform driver to present the logical device, and use I2C drivers from within that. Is this a good way to go? Are there better ways?
The logical device is a motor driver board and IR receiver. I have a simple diagram of its structure.
I'm looking to create two interfaces. The first similar to /sys/class/gpio where motors can be 'exported' and then accessed via reading and writing attributes. This would be useful for shell script access and quick debugging of the mechanical parts of the system attached to the motors. The second a character device node in /dev where data can be read or written in binary format, more useful for application control.
it seems not usual design, are you sure you have access to I2C bus of all chips ?
I think you should be able to talk only to MCU, and MCU should manage other devices.
Otherwise, why MCU is there ?
However, I cannot see your diagram, perhaps link is wrong.

Resources