Mehr Details zum USB-Gadget-Treiber

Geschrieben von MMind am Dienstag, 8. Februar 2011 in Oyo

Heute habe ich den Diff zwischen s3c-linux und Oyo-/Asus-Kernel noch etwas gesäubert. Dabei ist eine proprietäre ioctl-Schnittstelle, ein USB-Testmodus und weiteres Geschreibsel im Mülleimer gelandet, da diese Teile nur das Lesen des Diffs erschweren.

Das Ergebnis ist jetzt recht handlich — nun heißt es nur noch herauszufinden, was genau anders ist.

Update 09.02.2011: Ich habe die geänderten Bits noch etwas weiter untersucht.

diff --git a/s3c-udc-hs.c b/s3c-udc-hs.c
index db73d82..85769b3 100644
--- a/s3c-udc-hs.c
+++ b/s3c-udc-hs.c
@@ -253,24 +253,11 @@ static void udc_disable(struct s3c_udc *dev)
 	dev->usb_address = 0;
 
 	/* usb power disable */
-#if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
-	s3c2410_gpio_pullup(S3C2443_GPH14, 1); /* pull-down enable */
-	s3c2410_gpio_pullup(S3C2410_GPF2, 1);  /* pull-down enable */
-#else
-	s3c2410_gpio_pullup(S3C2443_GPH14, 2); /* pull-down enable */
-#endif
-	s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
-	s3c2410_gpio_setpin(S3C2443_GPH14, 0);
-
-	/* usb clock disable */
-	__raw_writel(0, S3C_UCLKCON);
-
-	/* USB Port is Suspend mode */
-	__raw_writel(__raw_readl(S3C2410_MISCCR)|(1<<12), S3C2410_MISCCR);
-
-	/* PHY power disable */
-	__raw_writel(__raw_readl(S3C_PWRCFG)&~(1<<4), S3C_PWRCFG);
-
+	if ((readl(S3C2410_GPHDAT) && (1 << 11)) == 0) {
+		s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
+		s3c2410_gpio_setpin(S3C2443_GPH14, 0);
+	}
+	__raw_writel((0 << 31) | (0 << 2) | (1 << 1) | (1 << 0), S3C_UCLKCON);
 }
 
 /*

Das deaktivieren des Gadget-Ports muss uns an dieser Stelle noch nicht interessieren — erstmal muss er ja aktiv sein :-) .

@@ -314,14 +301,14 @@ static int udc_enable(struct s3c_udc *dev)
 	DEBUG_SETUP("%s: %p\n", _FUNCTION_, dev);
 
 	/* usb power enable, vbus detect pull-up/down disable */
-#if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
-	s3c2410_gpio_pullup(S3C2443_GPH14, 2); /* usb power pull-up enable */
-	s3c2410_gpio_pullup(S3C2410_GPF2, 0);  /* vbus detect pull-up/down disable */
-#else
-	s3c2410_gpio_pullup(S3C2443_GPH14, 0); /* usb power pull-up enable */
-#endif
 	s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
-	s3c2410_gpio_setpin(S3C2443_GPH14, 1); 	/* usb power enbale */
+	s3c2410_gpio_setpin(S3C2443_GPH14, 1);	/* USB20_EN */
+	/*Qisda,2009/8/14,Leo SJ Yang{*/
+	/*Set GPD13,GPD14 as C_MODE and USB_SEL for EVT2*/
+	/*Qisda,2009/09/02,Leo SJ Yang{*/
+	s3c2410_gpio_cfgpin(S3C2410_GPD13, S3C2410_GPD13_OUTP);
+	s3c2410_gpio_setpin(S3C2410_GPD13, 1);	/* C_MODE */
+	/*Qisda,2009/09/02,Leo SJ Yang}*/
 
 	mdelay(1);
 

Der GPF2 auf dem smdk-Board ist der VBUS-IN — bei uns ist dies der GPG1. Dessen »pullup«, genauso wie der vom GPH14 erfolgt woanders — ich habe auch immer noch nicht verstanden was so ein »pullup« überhaupt ist. Was tut aber der GPD13?

@@ -340,16 +327,29 @@ static int udc_enable(struct s3c_udc *dev)
 	 * phy reset can reset bellow registers.
 	 */
 	/* PHY 2.0 S/W reset */
-	__raw_writel((0<<2)|(0<<1)|(1<<0), S3C_URSTCON);
+	/*Qisda,Leo SJ Yang,2009/09/09{ */
+	/*Fixed 3G module can not work after running Mass storage */
+	__raw_writel((0 << 2) | (1 << 0), S3C_URSTCON);
+	/*}Qisda,Leo SJ Yang,2009/09/09 */
+	/*Fixed 3G module can not work after running Mass storage */
 	mdelay(1); /* phy reset must be asserted for at 10us */
 	
 	/*Function 2.0, Host 1.1 S/W reset*/
-	__raw_writel((1<<2)|(1<<1)|(0<<0), S3C_URSTCON);
-	__raw_writel((0<<2)|(0<<1)|(0<<0), S3C_URSTCON);
+	/*Qisda,Leo SJ Yang,2009/09/09{ */
+	/*Fixed 3G module can not work after running Mass storage */
+	__raw_writel((1 << 2) | (0 << 0), S3C_URSTCON);
+	__raw_writel((0 << 2) | (0 << 0), S3C_URSTCON);
+	/*}Qisda,Leo SJ Yang,2009/09/09 */
+	/*Fixed 3G module can not work after running Mass storage */
 	

Aus den drei writel-Anweisung ist die Folge 0, 1, 0 für das Bit-1 herausgefallen. In den Konstantendefinitionen der neuen Implementierung taucht dieses Bit gar nicht mehr auf.

 	/* 48Mhz,Oscillator,External X-tal,device */
-	__raw_writel((0<<3)|(1<<2)|(1<<1)|(0<<0), S3C_PHYCTRL);
+	/*Qisda,Leo SJ Yang,2009/09/09{ */
+	/*Fixed 3G module can not work after running Mass storage */
+	__raw_writel((0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), S3C_PHYCTRL);
+	//the samsung solution for 3G and audio confliction  /*leo/joey 2009/12/23*/
 
+	/*}Qisda,Leo SJ Yang,2009/09/09 */
+	/*Fixed 3G module can not work after running Mass storage */
 	/* 48Mhz clock on ,PHY2.0 analog block power on
 	 * XO block power on,XO block power in suspend mode,
 	 * PHY 2.0 Pll power on ,suspend signal for save mode disable

Hier werden zwei Bits auf 0 statt auf 1 gesetzt. Die Konstanten im aktuellen Kernel bezeichnen die Operation (1<<2) als S3C2443_PHYCTRL_EXTCLK und die Operation (1<<1) als S3C2443_PHYCTRL_PLLSEL. Klingt erstmal interessant. Die anderen beiden Bits werden auch in der neuen Implementierung, wie hier, auf 0 gesetzt

@@ -359,7 +359,13 @@ static int udc_enable(struct s3c_udc *dev)
 	/* D+ pull up disable(VBUS detect), USB2.0 Function clock Enable,
 	 * USB1.1 HOST disable, USB2.0 PHY test enable
 	 */
-	__raw_writel((0<<31)|(1<<2)|(0<<1)|(1<<0), S3C_UCLKCON);
+	/*Qisda,Leo SJ Yang,2009/09/09{ */
+	/*Fixed 3G module can not work after running Mass storage */
+	/*Qisda Leo SJ Yang 2009/12/10 */
+	/*Fix the issue ,the 3G can not work after playing audio */
+	__raw_writel((0 << 31) | (1 << 2) | (1 << 1) | (1 << 0), S3C_UCLKCON);
+	/*}Qisda,Leo SJ Yang,2009/09/09 */
+	/*Fixed 3G module can not work after running Mass storage */
 
 	__raw_writel(IRQ_USBD, S3C2410_INTPND);
 	__raw_writel(IRQ_USBD, S3C2410_SRCPND);

Der Wert des Bit-1 ist anders — hat scheinbar was mit dem USB-Host zu tun. Für den ganzen Block gibt es auch keine Entsprechung im aktuellen Kernel. Vermutlich sollte hier einfach nur etwas ausgeschaltet werden bevor dann in den Interrupts herumgeschrieben wird.

@@ -371,7 +377,12 @@ static int udc_enable(struct s3c_udc *dev)
 	/* D+ pull up , USB2.0 Function clock Enable,
 	 * USB1.1 HOST disable,USB2.0 PHY test enable
 	 */
+	/*Qisda,Leo SJ Yang,2009/09/09{ */
+	/*Fixed 3G module can not work after running Mass storage */
 	__raw_writel((1<<31)|(1<<2)|(0<<1)|(1<<0), S3C_UCLKCON);
+	//samsung solution for 3G and audio conflict  /*leo/joey 2009/12/23*/
+	/*}Qisda,Leo SJ Yang,2009/09/09 */
+	/*Fixed 3G module can not work after running Mass storage */
 	
 	DEBUG_SETUP("S3C2443 USB Controller Core Initialized\n");
 	

Hier scheinbar nur Kommentare dazu gekommen. (1<<31)|(1<<2)|(0<<1)|(1<<0) entspricht auch dem S3C2443_UCLKCON_DETECT_VBUS | S3C2443_UCLKCON_FUNC_CLKEN | S3C2443_UCLKCON_TCLKEN des neuen Treibers. Nur das 0<<1 ist gar nicht mehr spezifiziert — scheint aber etwas mit dem USB-Host zu tun zu haben, wenn der Kommentar korrekt ist.

@@ -911,9 +922,9 @@ static void reconfig_usbd(void)
 	__raw_writel(0x0000, S3C_UDC_EP0_CON_REG);
 
 	/* EP1, EP2 dual FIFO mode enable */
-	usb_write(0x0080, (u32) S3C_UDC_EP_CON_REG, 1);
+/*Qisda qube for fix mass storage bug*/
 	usb_write(0x0080, (u32) S3C_UDC_EP_CON_REG, 2);
-
+/*Qisda qube for fix mass storage bug*/
 	__raw_writel(0, S3C_UDC_INDEX_REG);
 
 }

Was auch immer reconfig_usbd tun soll — es dürfte unser Initialisierungsproblem erstmal nicht betreffen — hoffe ich mal.

@@ -1959,6 +1970,13 @@ static int s3c_udc_probe(struct platform_device *pdev)
 		printk(KERN_INFO "failed to find usb-device clock source\n");
 		return -ENOENT;
 	}
+
+	/*Qisda Leo SJ Yang 2009/11/04 udc power state{*/
+	/*turn off USB EN20 when charger in unplug*/
+	s3c2410_gpio_cfgpin(S3C2443_GPH14,S3C2443_GPH14_OUTP);
+	s3c2410_gpio_setpin(S3C2443_GPH14,0);/* USB20_EN */
+	/*turn off USB_EN20 when charger is unplug*/
+	/*}Qisda Leo SJ Yang 2009/11/04 udc power state*/
 	clk_enable(udc_clock);
 
 	local_irq_disable();

Sie scheinen den Gadget-Port standardmäßig beim Start zu deaktiveren.

Die schicke Diff-Darstellung ist übrigens eine Kombination von

git diff --color
und des Skriptes ansi2html.

0 Kommentare Mehr...

Tango einmal anders

Geschrieben von MMind am Sonntag, 6. Februar 2011 in Oyo

Der Oyo und auch alle anderen Reader der Familie verwendet den Touch-Controller Tango-S32 von Pixcir zum verarbeiten der Eingaben des Touchscreens.

Chip-Details

Auf der Seite des Herstellers Pixcir gibt es einen Vergleich der Leistung aller ihrer Touch-Controller. Besonders interessant ist, dass der Tango-S32 echte zwei Finger auf dem Display unterstützt — er ist also wirklich multitouch-fähig.

Die dort angegebene maximale Display-Diagonale von 5 Zoll pro Controller erklärt auch warum in den Readern zwei der Controller verbaut sind.

Treiber-Situation

Bis jetzt habe ich noch nicht mal versucht zu verstehen, was qisda-iic.c und s3c-ts-iic.c eigentlich tun — auf alle Fälle sieht es aber im Code wüst aus. Ganz zu schweigen davon, dass ich mir erst noch Wissen über I2C anlesen muss.

Dafür habe ich noch ein paar Geräte gefunden, die ebenfalls den Tango-S32 als Touch-Controller nutzen.

Eines dieser Geräte ist das Dell Streak. Für dieses gibt es sogar Quelltexte. Nur leider ist der dort enthaltene Code in auo-touch.c auch nicht wesentlich aufgeräumter.

Ein weiteres Gerät mit Pixcir-Controllern ist das Notion-Ink Adam wie man auf den FCC-Bilder bei Engadget sehen kann. Aber irgendwie glaube ich nicht, dass von dort jetzt besserer Code kommen wird.

So wie es aussieht gibt es auch einen Treiber der sich gerade in Richtung Kernel bewegt für die USB-Variante der Pixcir-Controller.

0 Kommentare Mehr...

Erste Schritte im Linux-Kernel

Geschrieben von MMind am Samstag, 5. Februar 2011 in Oyo

Die ebook-Reader aus der Qisda-Familie nutzen den bq24075 von Texas Instruments zum Laden des Akkus und zur Versorgung des restlichen Systems. Da es bereits einen regulator-Treiber für den bq24022 gibt, hielt ich diesen vom Funktionsumfang her für günstig um etwas in die Kernelentwicklung hineinzuschnuppern.

Details zum bq24075

Besonders interessant ist dass der Chip das System unabhängig von der Batterie versorgt. Das heißt zum einen sollte es möglich sein, den Reader ohne Akku zu betreiben und zum anderen könnte man die Ladelogik deaktivieren, wenn eine externe Stromquelle angeschlossen ist, um so den Akku zu schonen.

Ansonsten unterstützt er 3 Stromstärken zum laden des Gerätes. 100mA für USB-Anschlüsse die nicht mit Strom versorgt werden, 500mA für USB-Aschlüsse mit Stromversorgung und maximal 1,5A für externe Ladegeräte. Die Größe dieses Maximalstroms wird durch einen Widerstand festgelegt, der an einem Anschluss des Chips hängt und dessen Größe wir momentan noch nicht kennen.

Mein »Treiber«

Ich habe also mal angefangen in einer Kopie des bq24022-Treibers die entsprechende Logik für die zusätzlichen Ladezustände zu implementieren. Wegen der momentanen USB-Situation kann ich es noch nicht testen, aber kompilieren tuts erstmal.

Der Treiber steht zusammen mit ein paar weiteren Basteleien auf unserer oyo-hack-Mailingliste.

Wie weiter

Der weitere Weg, den ich bis jetzt in anderen board-Definitionen gesehen habe, scheint nun zu sein, den gpio-vbus-Treiber aus dem USB/OTG-Bereich zur Erkennung der angeschlossenen Stromquelle zu nutzen und das Ganze, also den bq2407x und den gpio-vbus, dann mit dem pda-power-Treiber zu verknoten. Dieser kümmert sich dann darum, je nach Stromversorgung die richtige Stromstärke im bq24075 einzustellen.

Und viola, schon würde die Stromversorgung stehen.

Den Teil mit den vielen Flüchen, während des Suchens eigenartiger Fehler, habe ich mal ausgelassen.

0 Kommentare Mehr...

Seite 1 von 1, insgesamt 3 Einträge

Suche

Nach Einträgen suchen in Outside the Walled Garden:

Das Gesuchte nicht gefunden? Gib einen Kommentar in einem Eintrag ab oder nimm per E-Mail Kontakt auf!