Mapping UART register address to kernel for writing device drivers - c

How will I map register addresses specifically UART registers to kernel for writing device drivers for UART?
I have gone through the omap-serial.c.But I did not find the mapping of the registers defined in it.
Is it different from the mapping of standalone UART driver?

As a device driver writer, it is your job to read the hardware documentation. The serial port documentation will specify the bits in the control and status registers and provide guidance on how to determine their addresses. Usually that guidance is in a system integrator's document.
Let's say your research determines that the UART's registers are at 0x31080220. Your code would then have:
struct resource *uart_res; // resource handle
uint *uart; // pointer to actual control/status registers
uart_res = request_mem_region (0x31080220, 4*4, "my_uart"); // map 16 bytes
if (!uart_res)
{
error ("unable to map memory region");
return -ENOMEM;
}
uart = ioremap (0x31080220, 4*4);
if (!uart)
{
release_mem_region (0x31080220, 4*4);
error ("unable to map");
return -ENOMEM;
}
Then you can use the uart pointer to access the registers.
status = ioread32 (uart + 0); // read the status register
iowrite32 (0xf0f0, uart + 4); // foo foo to control register
Give precise target information for the manufacturer, model, and options—just like an automobile—and someone will help you find the specifics.

Mapping uart in kernel may be definded as uart device (not driver) in the some place: kernel/arch/arm/'machine'/(devices | serial or some else).
Usualy there is no neet for mapping. When uart driver probe, it connects to device and create tty character driver. To operate tty from kernel, you may add your own line discipline to tty. Then user space progam can open needed ttySX port and attach it to your line discipline. Then your code in kernel will operates communication thrue the uart port (tty->driver).

Related

How to get IRQ Pins in PCI

I was creating some drivers and I found my self stuck in the IRQ Pins, my kernel uses IOAPIC and I don't know how this interrupt mechanism (IRQ Pins) works and how to get them and use them.
Can anyone give a detailled answer on how to use them to make interrupts work.
A PCI device can potentially use up to 4 interrupt pins INTA#, INTB#, INTC# and INTD#. These signals will be wired to the interrupt controller. They are level-sensitive and may be shared by other PCI devices. If it has a single PCI function it will typically use INTA# if it uses one at all. If it has multiple PCI functions, the different PCI functions (up to 8) may use different interrupt pins or share the same one.
The read-only "Interrupt Pin" register at offset 3Dh in the PCI function's Type 00h configuration header says which interrupt pin the PCI function is using: 0 = none, 1 = INTA#, 2 = INTB#, 3 = INTC#, 4 = INTD#.
The read-write "Interrupt Line" register at offset 3Ch in the Type 00h configuration defines which IRQ number has been assigned to the PCI function by the system firmware (BIOS) or operating system. This IRQ number may be shared by other devices in the system.
Drivers don't usually care much about the "Interrupt Pin" register. They are more interested in the "Interrupt Line" register value set up by the firmware or operating system. Operating systems usually provide this information in a more friendly way than the driver having to retrieve the information directly from the PCI configuration memory.

Handling PCI read/write to configuration space in a QEMU device

I'm working on implementing a simple PCI device in QEMU and a kernel driver for it, and I have some trouble with handling pci_read/write_config_* function calls from the device side.
Unlike simple rw operations on a memory mapped bar, where the MemoryRegionOps callbacks receive the exact offset used by the driver, the config_read/write callbacks implemented as members in PCIDevice struct, receive an address that went through some manipulations/mapping that I have a hard time understanding.
Following the code path up to pci_config_host_read/write in QEMU sources, and the same in the kernel side for pci_read/write_config_* functions, didn't provide any clear answers.
Can anyone help me understand how to extract the config offset used by the driver when calling the pci config rw functions?
If you set your PCI device model up to implement the QEMU PCIDevice config_read and config_write methods, the addresses passed to them should be the offsets into the PCI config space (ie starting with the standard 0 == PCI_VENDOR_ID, 2 == PCI_DEVICE_ID, 4 == PCI_COMMAND and so on, and any device-specific stuff after the 64 bytes of standardized config space).

read() and write() using spi device driver

I would use the read() and write() for the /dev/spiB.C which is created by the user mode spi device driver (spidev.c). Now, the SPI ransaction message follows a certain format (e.g., 24 bits, with some bits for address and some bits for data) which is defined by the chip-vendor-specific spi controller driver. How is the message format fit into the read() and write() transaction? Where and how should I define the format in the code before or after the write() or read()?
Thanks!
You need to call spidev_ioctl() mentioned in spidev.c
E.g. Just check switch case :SPI_IOC_RD_BITS_PER_WORD which sets the bits/word (line 410).
Then finally it writes to the bits_per_word member in the spi device structure (line 415).
This spi pointer is the pointer of the spi device which you are communicating to and has been allocated during spidev_probe().
Definitely you need to set the configuration before r/w.You also need to set speed and mode of SPI.
I have refered to the below link for spidev.c file:
http://lxr.free-electrons.com/source/drivers/spi/spidev.c

how to use ioremap() api from user space to read and write registers on SPI Flash memory in uClinux

I am writing one sample application which is used to read registers and write particular value on given SPI Device address.
I am using altera spi 1.0 driver and got base address as 0xE5002460 while registering spi device.
I want to read/write registers from SPI Flash from user space using ioremap call.
Is there any code snippet or any example about how to use ioremap function which can directly read value of registers from base address given without writing any specific driver for that?
#Ritesh, ioremap api is used in the kernel space to memory map the device/module for ex:SPI registers which returns virtual address. This address can be used only by ioread[8|16|32] and iowrite[8|16|32] api's to read or write to the spi registers. You can use mmap to map the SPI registers. Go through the link mmap slower than ioremap.

RS232 Serial Pin Read in C in Linux

Ist there any possibility to read values from the pins of the COM Port? Any solution in C under Linux is appreciated!
Yes, see for instance this guide.
You use the ioctl() function, to read the various control pins. Data is, of course, best read through the normal read() handling, you don't want to be polling asynchronuous serial data.
I don't think your assumption (expressed in a comment) that the driver must check the pin-states to handle data is correct, normally a serial port is "backed" by an UART and that typically handles the RX/TX pins in hardware.
Am pretty sure , you can't read/write pins of UART.
Even at the hardware level , you have to read/write an entire byte.There is no bit access or read/write pin access.
The Byte is read/written in the Receive/Transmit UART buffer .
In either ways you can't just access the buffer directly , on your behalf the linux driver will do the job. You just have to make use of the driver in your application , to work with the UART , the linux driver for UART provides , standard API's like open(),read(),write(),ioctl() through which you interact the UART device.
If you want to work with drivers , and new to this field , the best place to start will be
this book.
The exact answer to this question depends on the precise hardware in question. I know of a piece of code where I worked, based on receiving the letter 'a' as the indication of bitrate, and it would poll the RX pin to detect the transitions between 0 and 1 to detect the "width" of the bits, and it would then calculate the correct clock-rate for the serial port and configure the serial port to match the bitrate of the other end.
A "PC" type hardware solution will not be able to read the RX/TX pins. In other hardware, it may be possible to do so. Many embedded systems allow various pins to be configured as inputs, outputs or "have a function" (in our case, RX, TX, CTS, RTS, etc) - so for example, you could configure the RX pin to be a input, and thus read the state of it. Of course, the normal serial port drivers will probably set these pins to "have a function" [or expect the boot code running before the kernel is started to have configure it this way]. So you would have to reconfigure the pins in some kernel code of your own, most likely. Beware that this may cause unexpected side-effects with the driver for the actual serial port - it may "get upset" when it tries to do things to the serial port and it's "not working as expected" because it's been "misconfigured".
You can almost certainly read (and/or write) the state of the control pins, such as CTS, RTS via IOCTL calls.

Resources