Bug 21030

Summary: Отсутствует поддержка web-камеры Genius Slim 322
Product: Sisyphus Reporter: Vladimir <vl_buharin>
Component: kernel-modules-v4l-std-defAssignee: Anton V. Boyarshinov <boyarsh>
Status: NEW --- QA Contact: qa-sisyphus
Severity: normal    
Priority: P3 CC: boyarsh, glebfm, kernelbot, ldv, mike, mithraen, rider, sbolshakov, shrek, sin, vitty, vsu, vt, zerg
Version: unstable   
Hardware: x86   
OS: Linux   
Attachments:
Description Flags
microdia-hack-0.patch
none
microdia-hack-1.patch
none
microdia-hack-2.patch
none
Лог USB-сниффера none

Description Vladimir 2009-08-11 09:43:28 MSD
Параметры камеры:

Определяется как 0458:702f KYE Systems Corp. (Mouse Systems).
Произведена на базе чипа
SONIX
SN9C201FG
065NAC21
В ядре 2.6.30 есть поддержка устройств на базе SN9C20X.
В списке есть близкое по значению кода вендора и продукта устройство.
sonixj		0458:702e	Genius Slim 310 NB
Comment 1 Sergey Vlasov 2009-08-11 20:15:08 MSD
(В ответ на комментарий №0)
> В ядре 2.6.30 есть поддержка устройств на базе SN9C20X.
На самом деле только в 2.6.31:
http://groups.google.com/group/microdia/browse_thread/thread/c7f74b3bd9b22482

Есть также вариант этого драйвера для сборки отдельно от ядра:
http://repo.or.cz/w/microdia.git

Впрочем, идентификатора 0458:702f в этом драйвере всё равно пока ещё нет - есть только 0458:7029:

        {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},

Для добавления поддержки, помимо чипа контроллера SN9C201FG, придётся ещё каким-то образом выяснить тип сенсора и его адрес на шине I2C. В настоящее время поддерживаются следующие типы сенсоров:

#define SENSOR_OV9650   0
#define SENSOR_OV9655   1
#define SENSOR_SOI968   2
#define SENSOR_OV7660   3
#define SENSOR_OV7670   4
#define SENSOR_MT9V011  5
#define SENSOR_MT9V111  6
#define SENSOR_MT9V112  7
#define SENSOR_MT9M001  8
#define SENSOR_MT9M111  9
#define SENSOR_HV7131R  10
#define SENSOR_MT9VPRB  20
Comment 2 Vladimir 2009-08-11 22:21:02 MSD
Я так понимаю один из вариантов разобрать камеру и отпаять сенсор?
Руки у меня кривые для тонкой пайки.
Можно ли как-нибудь опытным путем определить из командной строки тип сенсора или какой адрес?
Т.е. посылая какой либо специализированный запрос.
Или без драйвера ничего не выйдет?
Comment 3 Sergey Vlasov 2009-08-12 09:22:57 MSD
Можно попробовать и перебором (адрес обычно привязан к типу сенсора), пересобирая драйвер с разными вариантами записи в таблице устройств и проверяя, что получится. А вот проверять такой драйвер через запись в new_id в sysfs уже не выйдет - для USB нет возможности задать значение поля driver_data.
Comment 4 Vladimir 2009-09-01 16:42:04 MSD
Методом "научного" тыка определил, что ближайший сенсор HV7131R, адрес выставил 10.
Собрал драйвер. 

dmesg
usb 2-3: new high speed USB device using ehci_hcd and address 12
usb 2-3: New USB device found, idVendor=0458, idProduct=702f
usb 2-3: New USB device strings: Mfr=0, Product=1, SerialNumber=0
usb 2-3: Product: USB20 Camera
usb 2-3: configuration #1 chosen from 1 choice
sn9c20x: SN9C20X USB 2.0 Webcam - 0458:702F plugged-in.
sn9c20x: I2C slave 0x10 returned error during write to address 0x02
sn9c20x: Detected HV7131R Sensor.
sn9c20x: Webcam device 0458:702F is now controlling video device /dev/video0
input: SN9C20X Webcam as /devices/pci0000:00/0000:00:1d.7/usb2/2-3/input/input17
sn9c20x: I2C slave 0x10 returned error during write to address 0x01
sn9c20x: I2C slave 0x10 returned error during write to address 0x01
sn9c20x: I2C slave 0x10 returned error during write to address 0x30
sn9c20x: No ack from I2C slave 0x10 for write to address 0x25
sn9c20x: Using yuv420 output format

Из-за чего могут быть ошибки?

При помощи команды

LD_PRELOAD=/usr/lib/libv4l/v4l2convert.so mplayer tv:// -tv driver=v4l2:width=640:height=480:fps=25:device=/dev/video0 -vo x11

я себя вижу, но изображение с искаженными цветами.
Сильно искаженное изображение удалось добиться и с другим сенсорами.
Не силен в матчасти. В каком направлении копать?
Comment 5 Sergey Vlasov 2009-09-01 18:10:46 MSD
(В ответ на комментарий №4)
> Методом "научного" тыка определил, что ближайший сенсор HV7131R, адрес выставил
> 10.

> sn9c20x: I2C slave 0x10 returned error during write to address 0x02

Похоже, по этому адресу сенсор не отвечает. Для HV7131R стоит попробовать адрес 0x11 - в остальных камерах с этим сенсором используется именно такой адрес. При проверке других типов сенсоров имеет смысл использовать адрес, который встречается вместе с этим сенсором в имеющихся записях sn9c20x_table[].
Comment 6 Vladimir 2009-09-02 18:46:03 MSD
Копаясь в драйверах под виндов выяснил, что действительно используется сенсор HV7131R. ПО умолчанию в inf файле есть только устрой
Comment 7 Vladimir 2009-09-02 18:54:51 MSD
Копаясь в драйверах под виндовс, выяснил, что действительно используется сенсор
HV7131R. По умолчанию в inf файле есть только устройство с идентификатором
0458:7029. Но при установке драйверов создается oem80.inf файл, в котором
прописывается строчка с идентификатором моей камеры. Похоже парметры камер
идентичны.
При сборке указал адрес 0x11.
Результат после подключние камеры:
usb 2-3.1: new high speed USB device using ehci_hcd and address 4
usb 2-3.1: New USB device found, idVendor=0458, idProduct=702f
usb 2-3.1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
usb 2-3.1: Product: USB20 Camera
usb 2-3.1: configuration #1 chosen from 1 choice
sn9c20x: SN9C20X USB 2.0 Webcam - 0458:702F plugged-in.
sn9c20x: Detected HV7131R Sensor.
sn9c20x: Webcam device 0458:702F is now controlling video device /dev/video0
input: SN9C20X Webcam as
/devices/pci0000:00/0000:00:02.2/usb2/2-3/2-3.1/input/input7
sn9c20x: No ack from I2C slave 0x11 for write to address 0x25
sn9c20x: Using yuv420 output format
usbcore: registered new interface driver sn9c20x
sn9c20x: SN9C20x USB 2.0 Webcam Driver v2009.04 loaded
Похоже не может записать данные в 25-й регистр.

На все остальные адреса появляются дополнительные ошибки.
При тестировании зеленый экран.
Comment 8 Sergey Vlasov 2009-09-02 19:43:52 MSD
(В ответ на комментарий №7)
> sn9c20x: SN9C20X USB 2.0 Webcam - 0458:702F plugged-in.
> sn9c20x: Detected HV7131R Sensor.
> sn9c20x: Webcam device 0458:702F is now controlling video device /dev/video0
> input: SN9C20X Webcam as
> /devices/pci0000:00/0000:00:02.2/usb2/2-3/2-3.1/input/input7
> sn9c20x: No ack from I2C slave 0x11 for write to address 0x25

Похожие ошибки были и с камерой Genius Look 320S (0458:7029):
http://lists.altlinux.org/pipermail/hardware/2009-April/015012.html

Можно попробовать попатчить дальше - к сожалению, только методом тыка, но по крайней мере загрузка данных из hv7131r_init сейчас проходит без ошибок.
Comment 9 Sergey Vlasov 2009-09-02 19:46:16 MSD
Created attachment 3826 [details]
microdia-hack-0.patch

Для начала можно попробовать понизить скорость обмена - все остальные сенсоры используют для I2C частоту 100 кГц, и только для HV7131R выбирается 400 кГц; возможно, на повышенной скорости некоторые экземпляры камер не работают.
Comment 10 Sergey Vlasov 2009-09-02 19:48:41 MSD
Created attachment 3827 [details]
microdia-hack-1.patch

Если понижение скорости не поможет, можно перейти на однобайтовые передачи вместо записи 3 байт сразу - при загрузке hv7131r_init используются однобайтовые передачи, которые сейчас вроде бы работают.
Comment 11 Sergey Vlasov 2009-09-02 19:50:06 MSD
Created attachment 3828 [details]
microdia-hack-2.patch

Если после microdia-hack-1.patch ошибка переедет на адрес 0x30, можно перейти на проверенную при инициализации функцию sn9c20x_write_i2c_data() и там (отличие в последнем байте пакета, передаваемого по USB, точное назначение которого неизвестно).
Comment 12 Vladimir 2009-09-03 01:05:07 MSD
В моем случае достаточно было заменить в строке
ret = sn9c20x_write_i2c_data_ext(dev, 3, 0x25, buf, 0x1e);
0x1e на 0x00 или 0x06 (остальные не проверял) и ошибка пропала. (в файле hv7131r.c)

Результат:
usb 3-3.2: new high speed USB device using ehci_hcd and address 9
usb 3-3.2: New USB device found, idVendor=0458, idProduct=702f
usb 3-3.2: New USB device strings: Mfr=0, Product=1, SerialNumber=0
usb 3-3.2: Product: USB20 Camera
usb 3-3.2: configuration #1 chosen from 1 choice
sn9c20x: SN9C20X USB 2.0 Webcam - 0458:702F plugged-in.
sn9c20x: Detected HV7131R Sensor.
sn9c20x: Webcam device 0458:702F is now controlling video device /dev/video0
input: SN9C20X Webcam as /devices/pci0000:00/0000:00:02.2/usb3/3-3/3-3.2/input/input12
sn9c20x: Using yuv420 output format
usbcore: registered new interface driver sn9c20x
sn9c20x: SN9C20x USB 2.0 Webcam Driver v2009.04 loaded

Но изображение оставляет желать лучшего. Искаженные цвета.
Comment 13 Vladimir 2009-09-03 11:42:29 MSD
Опытным путем выяснил, что ошибка возникает только при записи в регистр 25, 26, 27 значений начинающихся с нечетного числа (1x,3x,5x,...,Fx).
Так же выдает ошибку если строчка выглядит следующим образом:
  
ret = sn9c20x_write_i2c_data(dev, 3, 0x25, buf);

Из-за чего может происходить искажение цветов (цветной снег)? Неправильная инициализация устройства?
Comment 14 Sergey Vlasov 2009-09-03 12:12:31 MSD
(В ответ на комментарий №13)
> Опытным путем выяснил, что ошибка возникает только при записи в регистр 25, 26,
> 27 значений начинающихся с нечетного числа (1x,3x,5x,...,Fx).

Есть предположение, что в этом случае запись в регистр просто не выполняется. microdia-hack-1.patch (3 однобайтовые записи вместо одной 3-байтовой) тоже не работает?

> Из-за чего может происходить искажение цветов (цветной снег)? Неправильная
> инициализация устройства?
Так это совершенно неправильные цвета, или цветной шум на в принципе нормальном изображении? Регистры 0x25...0x27 задают время экспозиции кадра - возможно, значение по умолчанию недостаточно для имеющейся освещённости, а правильное туда по каким-то причинам не записывается.

Можно ещё покрутить параметр gain (если непонятно, чем его менять в интерфейсе, все параметры доступны в sysfs - искать в районе /sys/class/video4linux/...). Вероятнее всего, при низкой освещённости всё-таки нужно поднимать exposure, но для этого нужно разбираться с записью.
Comment 15 Vladimir 2009-09-03 12:59:01 MSD
Применил 0-й и 1-й патчи.
Функция выглядит так:
int hv7131r_set_exposure(struct usb_sn9c20x *dev)
{
	__u8 buf[3];
	int ret;
	__u32 val;

	val = ((dev->vsettings.exposure << 8) * 0xffffff) / 0xffff;

	buf[0] = (val >> 16) & 0xff;
	buf[1] = (val >> 8) & 0xff;
	buf[2] = val & 0xff;

	ret = sn9c20x_write_i2c_data(dev, 1, 0x25, &buf[0]);
	if (ret >= 0)
	ret = sn9c20x_write_i2c_data(dev, 1, 0x26, &buf[1]);
	if (ret >= 0)
	ret = sn9c20x_write_i2c_data(dev, 1, 0x27, &buf[2]);
 
 return ret;

	return ret;
}


Результат:
No ack from I2C slave 0x11 for write to address 0x25
(Прошу прощения за множество кодов. Пока не научился делать diff и patch)
Comment 16 Vladimir 2009-09-03 14:07:51 MSD
Применил все 3 патча. Ошибки пропали, но изображения нет. Только зеленый экран с рябью в верхней области.
Comment 17 Michael Shigorin 2009-09-04 01:45:48 MSD
(In reply to comment #15)
> (Прошу прощения за множество кодов. Пока не научился делать diff и patch)
diff -u file.orig file
diff -Naur dir.orig/ dir/ > dir-fixdescription.patch

*.diff и *.patch -- обычно разные суффиксы одного и того же.
Comment 18 Vladimir 2009-09-05 02:38:45 MSD
>diff -u file.orig file
>diff -Naur dir.orig/ dir/ > dir-fixdescription.patch
Благодарю за подсказку!
Играясь с значениями регистров мне удалось пару раз избавиться от цветного шума. Но эффект действовал до перезагрузки компьютера. Повторить не удалось. Складывается ощущение, что регистры помнят предыдущие значения. Или сопутствующие подгружаемые модули повторяют предыдушие параметры.
Вот тут https://groups.google.com/group/microdia/web/howto-write-your-init-driver-function описывается как по логам USB sniffer-а добавить функцию в драйвер. Но как это сделать я не понял. Я сделал логи сниффером при передергивании камеры, но не понял где брать значения для записи в регистры. Может это поможет как-то исправить глюки с шумами?
Comment 19 Vladimir 2009-09-05 02:41:12 MSD
Created attachment 3847 [details]
Лог USB-сниффера
Comment 20 Michail Yakushin 2010-07-02 18:38:10 MSD
камера по прежнему не работает?
Comment 21 Vladimir 2010-07-03 22:25:47 MSD
Пробовал собирать пакет kernel-modules-v4l-std-def для ядра 2.6.32. Добавил в файл sn9c20x.c (если не изменяет мне память) ID своего устройства. Собралось. Драйвер работает, но изображение как и с драйвером microdia с цветной рябью.