I2C Mux on Linux - linux

I am trying to understand how to address devices behind I2C Mux like PCA9548 in linux.
If the topology is something like
CPU->I2C_A Controller->PCA9548->Channel 0->RTC
CPU->I2C_A Controller->PCA9548->Channel 1->Temp Sensor
CPU->I2C_B Controller->PCA9548->Channel 0->Voltage Sensor
CPU->I2C_B Controller->PCA9548->Channel 1->Speed Sensor
I want to know the representation of these devices in user space? What are the associated sysfs entries?
I also want to know if pc9548 is the only driver required in kernel and i2c-dev and i2c-core are already available? Or driver for RTC/sensors is also required?
I have tried to read this, but could not follow it much.
My requirement is to read/write to those devices from user space. Do I have to instantiate devices and assign addresses to it in startup script?
Thanks,
Hemant

You could use i2c-tools for manipulation at user space, if the driver has some problem.
Also you'll need enable the kernel module "i2c-dev" for the char device.
Like /dev/i2c-0
link here.
The necessary driver are i2c-mux, pca954x, I believe you already have i2c-core.
Also you should describe all the I2C devices in device tree or other files.
If the driver is prepared, you may see 8 i2c adapters under /dev, and their salve device is under /sys/bus/i2c.

Related

How to set chip select in SPI programming for multipleslaves ? (struct spi_ioc_transfer)

Maybe I am asking the wrong question actually but I am just making my first steps in the embedded world. So I am sorry if the question is somehow stupid.
I am trying to program a software for 9DOF IMU in c++ and linux environment.
As far as I understood the SPI, the SS pin has to be low active in order for a transmission to occur. I have seen multiple reading or writing bytes function examples and all using the struct spi_ioc_transfer but they were all single slave examples and there is no mention about setting or configuring the SS in the code. Also When I check the structre of spi_ioc_transfer there is the cs_change however, how does it know which cs we are dealing with from the beginning ?
The chip select (CS or SS) to use is determined by which device node you open.
To talk to a SPI chip with the Linux spidev driver, you open a device such as /dev/spidev0.1. The numbers in the device node file name refer to the bus and chip select, respectively — in this example it would be the first bus (0) and the second CS (1). If you want to talk to devices on different chip-selects, you have to open different device nodes and do ioctls on the appropriate one.

MCP23017 I2C Device driver probe function is not called

I am using the following I2C/GPIO Device driver to access the MCP23017 GPIOs. With the insmod command I am able to load the driver and its listed in /proc/modules. I have two MCP23017 chips connected to my Raspberry Pi. Both are detected at addresses 0x20 and 0x21. The initcall to the driver registers the driver. I checked this by printing out a message. But the driver probe function is not called. The devices are not opened/ cannot be located elsewhere.
How is the probe function called?
Should the probe be done manually to locate the devices?
Is the probe call similar to the open call?
I tried this echo mcp23017 0x20 > new_device to manually create a new device with the address. But it didnt work. I got the followin message: Driver 'mcp23s08' is already registered, aborting...
Any help would be appreciated.
probe() function is called when driver is matched with your device description in Device Tree. Matching happens when compatible field of your driver found in Device Tree (for your driver it's "microchip,mcp23017" string).
Apparently you don't have your device (MCP23017) described in Device Tree, that's why probe() is not called. You can load corresponding Device Tree Overlay to overcome this issue. The one you pointed out in your comment seems to be correct. Read more about loading overlays in Raspberry Pi ecosystem here.
You can try to load your overlay like described in that article:
$ sudo dtoverlay mcp23017.dtbo
Or you can try to use Capemgr for this purpose. Personally I didn't try any of those, so you should look which works for you best.
Update
Replying to your questions in comments.
But when I try the i2cdetect command it shows UU.
See man i2cdetect. So "UU" means that i2cdetect skipped probing because device at the address you specified is already used by driver. I guess it what you intended, so it's ok.
With a rmmod mcp23017 command I see the device still under devices but i2cdetect shows 0x20
So you unloaded the driver and now i2cdetect shows you that there is some device on 0x20 address. I guess it's correct behavior. Also if you want to get rid completely of your device -- try to unload DT overlay along with driver.
Also I have connected two MCP23017 chips. But I can see only the device at 0x20 under devices. The I2C chip at 0x21 is still not detected, though the driver says it supports up to 8 chips
I can see two possible causes to this issue.
DT overlay only has description for device with 0x20 address, but missing description for device with 0x21 address. If this is the case, you should find sources for your DT overlay, add description for rest of your devices, compile that modified DT overlay and then load it instead of pre-built one.
All devices may be configured for using 0x20 address. See section 1.4
Hardware Address Decoder in MCP23017 datasheet for details. Check A0, A1, A2 pins on your chips.

i2cdetect doesn't find anything on goodix chip

I have a goodix chip for the touchscreen on my tablet PC and even though I compiled the latest kernel module for it, things are not working.
I am using exactly this kernel version with the patched driver:
https://github.com/NimbleX/kernel
For starters, the picture of the said chip is the following:
The DSDT tables contain information regarding the touchscreen.
From what I understand the touchscreen is connected via an I2C serial interface but lshw shows that *-serial is UNCLAIMED.
Nevertheless I can see that the i2c_i801 module for the SMBus controller is loaded.
With the help of Aleksei I was able to determine that the toucscreen is connected to i2c-1 buss and that the controller must use 0x14 or 0x5d address.
Unfortunatelly, i2cdetect doesn't find anything, as it can be seen here.
I created a lengthy gist with the output of the following:
dmesg
DSDT.dsl
lshw
lspci
lsusb
/proc/bus/input/devices
xinput
I know that some of these are redundant and that others are useless but nevertheless it's better to have where to search than to miss something out.
I measured with a multimeter and the chip is powered both when running Windows and Linux so this rules out that I need to somehow tell Linux to power this thing out.
So, what do do next in order to debug this thing?
Hi can you check where pin 5,6 are connected specifically 6 which is reset ic so if that may be reseting the ic. just a posiblity.

How to create an event# device for a virtual input device (/dev/input/js3) in linux kernel module?

i am writing a linux kernel module which takes N of real /dev/input/js# devices and proxifies them as a single /dev/input/js3 device. Currently my module is creating /dev/input/js3 just fine, jstest is happy with it, but not the real applications. I guess (strace'd) it is so because i have no matching pair of /dev/input/event# for my virtual js3 device. How do i create one from my module?
Here is my module's source, which probably has numerous of issues, but mostly working: https://github.com/iamtakingiteasy/unijoy/blob/master/unijoy.c
Here is an example, you can use
1. class_create to create the class specified for the device,
2. device_create to create the device node
3. cdev_init to initialize and
4. cdev_add to add the device to the /dev list
For example you can refer the below link :Create a device node in kernel module

PCM voice data on serial port to sound device conversion in linux

I have a telephony modem which gives voice to my interfaced application via a serial USB ttyUSB0 in 16bit PCM 8000hz. I am able to capture this data and play with audacity. I want this port to be detected as a sound device in linux (I am on ubuntu). Is it possible? Are there any other options?
I'm guessing you are using a huawei 3G modem or something similar which gives ttyUSB1 for audio. Make sure you have the serial driver binded to it. Then simply pass the port itself as a "file" for input for any program of your choice.You need root access for that.You figured out the audio settings so it must be enough.I have voice calling working in UBUNTU 11.10 with Huawei. So let me know if i can help any further.
Ok, I see it's very old question but answers helped me to get a right direction so I decided to help others.
The one way to achieve (in addition to below) what are you are
looking for is to write dynamic kernel module.
Have it register as a sound device, and check that it has a GSM
module present (which module is it exactly can be recognized in
dmesg, lsmod, or output).
Then establish communication between user space representation as a
sound card and serial usb module.
The other way is to get module that you recognized by dmesg, lsmod and extend its functionality as a sound card.
All are tricky tasks because:
in the first case you have to resolve intermodule communication at the kernel level...... which is, lets say, a little hard even if programmer has a right background in subject.
the second case is hard in that you have to deal with:
USB stack (which is little unpleasant for human beings) and
sound subsystem (which is a little burdensome because of historical issues).
Without being an experienced kernel programmer there are small chances to succeed.

Resources