How does Linux determine a device class? - linux

Linux newbie question.
Just wondering how Linux determines which device class a device is? Specifically, when I plug a barcode scanner in how does it know it is an ttyACM device? I have a scanner that works with my Linux OS but the new model isn't recognized so I'm wondering if I can alter a file somewhere in the system that tells it to recognize the scanner as ttyACM0 and use the existing drivers.

USB devices (I assume your scanner is USB) are identified by vendorId and productId (two 16bit integers), each driver fill an array with the list of supported vendor/prods id (creating a relation vendor:prod->driver), I guess at compile time all the id in the array are merged together in a list which then is used for a lookup search when a device is plugged in.
Usually you can see vendor and product id of the attached device with dmesg command right after the device is plugged in (or with lsusb).
For ttyACM see acm_ids[] in drivers/usb/class/cdc-acm.c
Careful playing around with device drivers, even being ttyACM a terminal interface only if the interface tty->hardware is implemented poorly some command may break the hardware.
Perhaps this question should be in Unix & Linux stackexchange

Related

python3 python-escpos: product id / PID for EPSON TM-M30 needed

Since some years I am running and maintaining an online P.O.S. system, where peripheral hardware and print system is managed by a RasPi with pure debian & python3.
My costumer bought a new receipt printer, which is an EPSON TM-M30.
Currently he's using a TM-T88IV for that.
The python-escpos printer code snippet currently is
p = printer.Usb(0x04b8, 0x0202, 0)
Do I need anything to change for the new printer (googeling since hours I cannot find a PID for this new printer)
I know that with the new printer ethernet an WiFi is also available and I can use
p = printer.Network("192.168.178.77", 0) // port might differ
for that, but stiil I want to be able to use it with USB if needed.
Notice: I found the same PID here
http://www.linux-usb.org/usb.ids
for the TM-T70 and I guess that the PID 0x0202 is valid for more than one thermal printer, but need to be sure.
Thanks for any helpful answers.
The interface board of the EPSON printer is modularized and commonly used by many printers.
Interface Board
UB-U
The PID is for that interface board and is the same for any printer that uses it.
For example, for Japanese materials, the PID is the same for TM-m30 and TM-T88VI.
TM-m30 page 86
TM-T88VI page 118
Therefore, VID 0x04B8 and PID 0x0202 can be considered as IDs of USB interface boards of EPSON printers.
If you can get the Manufacturer and Product String Descriptors written in the document, you will be able to determine the printer model.
The EPSON TM-m30 has a USB vendor ID of 04b8 and a USB product ID of 0e20.
lsusb on my RHEL 8 shows the printer as Seiko EPSON, 04b8:0e20.
You can use lsusb to find the vendor id and product id.
The following script will help you with that (see its readme for more details) and will also give you the endpoint ids: https://gist.github.com/elsholz/44643ede809a6c4a3875beaae26bff2f

Change default names for USB virtual serial ports in Linux

I am developing an embedded solution using C and I am working with two USB sensors. If I connect each sensor alone they take this names:
Device 1 (I do not know why it takes 6 names...)
/dev/ttyACM0
/dev/ttyACM1
/dev/ttyACM2
/dev/ttyACM3
/dev/ttyACM4
/dev/ttyACM5
/dev/ttyACM6
Device 2
/dev/ttyACM0
So when I start as an embedded system and both sensors are connected, the fastest one takes /dev/ACM0 but it not always the same. So, when I try to read device 2 I could be reading device 1...
I think that It would be great to change the default names of the sensors. I guess that it is going to be possible but I do not find anything.
You should try using the names in /dev/serial/by-id instead, since those names include the name of the device and should not depend on the order of connection.
By the way, it is also possible to write udev rules that make symbolic links for the serial ports depending on what device they belong to. I am not sure how that would work for a composite device with 6 serial ports, but there probably is a way to make it work.

I2C Mux on 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.

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.

How do I read events from a HID device under Ubuntu Jaunty?

I have a Linux USB HID device (a Hama MCE), and I can read its events manually by reading cat /dev/input/event7 and cat /dev/input/event8. Whenever I press a key on the device, a few bytes become available for reading with one of the cat commands above. I have a default installation of Ubuntu Jaunty 64-bit desktop on the machine.
I think I can write a parser to interpret the bytes emitted by the device, or I'll use libhid if it's more convenient.
My questions are:
How do I prevent the text-mode virtual consoles from receiving some of the key presses on the device as normal keypresses? As of now, some device keys result an Enter, a BackSpace, a PageUp or numeric keypad numbers.
Similarly, how do I prevent the X server from receiving keyboard and mouse events from this device? I have several USB keyboards and mice connected to the computer. I want the X server receive events from all of them, except for this device.
How do I set up that whenever the device gets connected to the computer, the command /usr/local/bin/keydumper /dev/input/event7 /dev/input/event8 (or one command for each /dev/ path) would get run, with the proper /dev/ paths substituted in the command line?
Answering my own question based on answers from the Linux USB HID driver developers:
Question 1. and 2.: Do
ioctl(open("/dev/input/event7", O_RDONLY), EVIOCGRAB, 1);
As long as this filehandle is open, the events generated would go only
to this filehandle (not to other open()s of the same device or to the
system keyboard or mouse event pool). At most one process can hold a
successful EVIOCGRAB at a HID device at a time. Lirc can be configured
to do an EVIOCGRAB.
Question 3.: Configure udev to start the program once the device is connected.
I do not have enough points to comment sadly.
If you are looking for the definition of EVIOCGRAB try
#include <linux/input.h>
I think solution for all questions can be writing own filter device driver, or custom driver for your device. I know such a thing (filter device driver) is available on windows so something similar can be on Linux. In that filter device driver you could block all unwanted events from the target device that you wish to block, I don't really get 3 question so I don't know how to answer for that.

Resources