static int __init omap_leds_init(void) { if (!cpu_class_is_omap1()) return -ENODEV; if (machine_is_omap_innovator()) leds_event = innovator_leds_event; else if (machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_perseus2()) leds_event = h2p2_dbg_leds_event; else if (machine_is_omap_osk()) leds_event = osk_leds_event; else return -1; if (machine_is_omap_h2() || machine_is_omap_h3() #ifdef CONFIG_OMAP_OSK_MISTRAL || machine_is_omap_osk() #endif ) { /* LED1/LED2 pins can be used as GPIO (as done here), or by * the LPG (works even in deep sleep!), to drive a bicolor * LED on the H2 sample board, and another on the H2/P2 * "surfer" expansion board. * * The same pins drive a LED on the OSK Mistral board, but * that's a different kind of LED (just one color at a time). */ omap_cfg_reg(P18_1610_GPIO3); if (gpio_request(3, "LED red") == 0) gpio_direction_output(3, 1); else printk(KERN_WARNING "LED: can't get GPIO3/red?\n"); omap_cfg_reg(MPUIO4); if (gpio_request(OMAP_MPUIO(4), "LED green") == 0) gpio_direction_output(OMAP_MPUIO(4), 1); else printk(KERN_WARNING "LED: can't get MPUIO4/green?\n"); } leds_event(led_start); return 0; }
static int __init osk_ts_probe(struct omap_ts_t *ts) { #ifdef CONFIG_OMAP_OSK_MISTRAL if (!machine_is_omap_osk()) return -ENODEV; /* Configure GPIO4 (pin M17 ZDY) as /PENIRQ interrupt input */ omap_cfg_reg(P20_1610_GPIO4); omap_request_gpio(4); omap_set_gpio_direction(4, 1); set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING); ts->irq = PEN_IRQ; /* Configure uWire interface. ADS7846 is on CS0 */ omap_uwire_configure_mode(ADS7846_UWIRE_CS, UWIRE_READ_RISING_EDGE | UWIRE_WRITE_RISING_EDGE | UWIRE_CS_ACTIVE_LOW | UWIRE_FREQ_DIV_2); /* FIXME verify there's really a Mistral board: * see if the AD7846 chip responds. */ /* NOTE: no VREF; must ignore the temp, VBAT, and AUX sensors */ return 0; #else return -ENODEV; #endif }
/** * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. * */ void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { dev_info(&pdev->dev, "remove: state %x\n", hcd->state); if (in_interrupt ()) BUG (); hcd->state = USB_STATE_QUIESCING; dev_dbg(&pdev->dev, "roothub graceful disconnect\n"); usb_disconnect (&hcd->self.root_hub); hcd->driver->stop (hcd); hcd_buffer_destroy (hcd); hcd->state = USB_STATE_HALT; if (machine_is_omap_osk()) omap_free_gpio(9); free_irq (hcd->irq, hcd); usb_deregister_bus (&hcd->self); omap_stop_hc(pdev); release_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); }
static int __init osk_tps_init(void) { if (!machine_is_omap_osk()) return 0; /* Let LED1 (D9) blink */ tps65010_set_led(LED1, BLINK); /* Disable LED 2 (D2) */ tps65010_set_led(LED2, OFF); /* Set GPIO 1 HIGH to disable VBUS power supply; * OHCI driver powers it up/down as needed. */ tps65010_set_gpio_out_value(GPIO1, HIGH); /* Set GPIO 2 low to turn on LED D3 */ tps65010_set_gpio_out_value(GPIO2, HIGH); /* Set GPIO 3 low to take ethernet out of reset */ tps65010_set_gpio_out_value(GPIO3, LOW); /* gpio4 for VDD_DSP */ /* FIXME send power to DSP iff it's configured */ /* Enable LOW_PWR */ tps65010_set_low_pwr(ON); /* Switch VLDO2 to 3.0V for AIC23 */ tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | TPS_LDO1_ENABLE); return 0; }
static int __init osk_soc_init(void) { int err; u32 curRate; struct device *dev; if (!(machine_is_omap_osk())) return -ENODEV; osk_snd_device = platform_device_alloc("soc-audio", -1); if (!osk_snd_device) return -ENOMEM; platform_set_drvdata(osk_snd_device, &osk_snd_devdata); osk_snd_devdata.dev = &osk_snd_device->dev; *(unsigned int *)osk_dai.cpu_dai->private_data = 0; /* McBSP1 */ err = platform_device_add(osk_snd_device); if (err) goto err1; dev = &osk_snd_device->dev; tlv320aic23_mclk = clk_get(dev, "mclk"); if (IS_ERR(tlv320aic23_mclk)) { printk(KERN_ERR "Could not get mclk clock\n"); return -ENODEV; } if (clk_get_usecount(tlv320aic23_mclk) > 0) { /* MCLK is already in use */ printk(KERN_WARNING "MCLK in use at %d Hz. We change it to %d Hz\n", (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK); } /* * Configure 12 MHz output on MCLK. */ curRate = (uint) clk_get_rate(tlv320aic23_mclk); if (curRate != CODEC_CLOCK) { if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) { printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n"); err = -ECANCELED; goto err1; } } printk(KERN_INFO "MCLK = %d [%d], usecount = %d\n", (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK, clk_get_usecount(tlv320aic23_mclk)); return 0; err1: clk_put(tlv320aic23_mclk); platform_device_del(osk_snd_device); platform_device_put(osk_snd_device); return err; }
static int __init osk_soc_init(void) { int err; u32 curRate; struct device *dev; if (!(machine_is_omap_osk())) return -ENODEV; osk_snd_device = platform_device_alloc("soc-audio", -1); if (!osk_snd_device) return -ENOMEM; platform_set_drvdata(osk_snd_device, &snd_soc_card_osk); err = platform_device_add(osk_snd_device); if (err) goto err1; dev = &osk_snd_device->dev; tlv320aic23_mclk = clk_get(dev, "mclk"); if (IS_ERR(tlv320aic23_mclk)) { printk(KERN_ERR "Could not get mclk clock\n"); err = PTR_ERR(tlv320aic23_mclk); goto err2; } /* * Configure 12 MHz output on MCLK. */ curRate = (uint) clk_get_rate(tlv320aic23_mclk); if (curRate != CODEC_CLOCK) { if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) { printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n"); err = -ECANCELED; goto err3; } } #ifdef CONFIG_DEBUG_PRINTK printk(KERN_INFO "MCLK = %d [%d]\n", (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK); #else ; #endif return 0; err3: clk_put(tlv320aic23_mclk); err2: platform_device_del(osk_snd_device); err1: platform_device_put(osk_snd_device); return err; }
static int __init omap_kp_probe(struct device *dev) { int i; /* Disable the interrupt for the MPUIO keyboard */ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); if (machine_is_omap_h2() || machine_is_omap_h3()) { keymap = h2_keymap; set_bit(EV_REP, omap_kp_dev.evbit); } else if (machine_is_omap_innovator()) { keymap = innovator_keymap; } else if (machine_is_omap_osk()) { keymap = osk_keymap; } else { keymap = test_keymap; } init_timer(&kp_timer); kp_timer.function = omap_kp_timer; /* get the irq and init timer*/ tasklet_enable(&kp_tasklet); if (request_irq(INT_KEYBOARD, omap_kp_interrupt, 0, "omap-keypad", 0) < 0) return -EINVAL; /* setup input device */ set_bit(EV_KEY, omap_kp_dev.evbit); for (i = 0; keymap[i] != 0; i++) set_bit(keymap[i] & 0x00ffffff, omap_kp_dev.keybit); omap_kp_dev.name = "omap-keypad"; input_register_device(&omap_kp_dev); if (machine_is_omap_h2() || machine_is_omap_h3()) { omap_cfg_reg(F18_1610_KBC0); omap_cfg_reg(D20_1610_KBC1); omap_cfg_reg(D19_1610_KBC2); omap_cfg_reg(E18_1610_KBC3); omap_cfg_reg(C21_1610_KBC4); omap_cfg_reg(G18_1610_KBR0); omap_cfg_reg(F19_1610_KBR1); omap_cfg_reg(H14_1610_KBR2); omap_cfg_reg(E20_1610_KBR3); omap_cfg_reg(E19_1610_KBR4); omap_cfg_reg(N19_1610_KBR5); omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING); } /* scan current status and enable interrupt */ omap_kp_scan_keypad(keypad_state); omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); return 0; }
/** * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. * */ void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { usb_remove_hcd(hcd); if (machine_is_omap_osk()) omap_free_gpio(9); omap_stop_hc(pdev); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); clk_put(usb_host_ck); }
static int __init omap_uwire_init(void) { spin_lock_init(&uwire_lock); uwire_write_reg(UWIRE_SR3, 1); if (machine_is_omap_h2() || machine_is_omap_osk()) { /* defaults: W21 SDO, U18 SDI, V19 SCL */ omap_cfg_reg(N14_1610_UWIRE_CS0); omap_cfg_reg(N15_1610_UWIRE_CS1); } return 0; }
/* * Board specific gang-switched transceiver power on/off. * NOTE: OSK supplies power from DC, not battery. */ static int omap_ohci_transceiver_power(int on) { if (on) { if (machine_is_omap_innovator() && cpu_is_omap1510()) fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); else if (machine_is_omap_osk()) tps65010_set_gpio_out_value(GPIO1, LOW); } else { if (machine_is_omap_innovator() && cpu_is_omap1510()) fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); else if (machine_is_omap_osk()) tps65010_set_gpio_out_value(GPIO1, HIGH); } return 0; }
/* * Hardware specific transceiver power on/off */ static int omap_ohci_transceiver_power(int on) { if (on) { if (machine_is_omap_innovator() && cpu_is_omap1510()) fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); else if (machine_is_omap_osk()) { /* FIXME: GPIO1 -> 1 on the TPS65010 I2C chip */ } } else { if (machine_is_omap_innovator() && cpu_is_omap1510()) fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); else if (machine_is_omap_osk()) { /* FIXME: GPIO1 -> 0 on the TPS65010 I2C chip */ } } return 0; }
static int __init osk_soc_init(void) { int err; u32 curRate; struct device *dev; if (!(machine_is_omap_osk())) return -ENODEV; osk_snd_device = platform_device_alloc("soc-audio", -1); if (!osk_snd_device) return -ENOMEM; platform_set_drvdata(osk_snd_device, &osk_snd_devdata); osk_snd_devdata.dev = &osk_snd_device->dev; *(unsigned int *)osk_dai.cpu_dai->private_data = 0; err = platform_device_add(osk_snd_device); if (err) goto err1; dev = &osk_snd_device->dev; tlv320aic23_mclk = clk_get(dev, "mclk"); if (IS_ERR(tlv320aic23_mclk)) { printk(KERN_ERR "Could not get mclk clock\n"); return -ENODEV; } curRate = (uint) clk_get_rate(tlv320aic23_mclk); if (curRate != CODEC_CLOCK) { if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) { printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n"); err = -ECANCELED; goto err1; } } printk(KERN_INFO "MCLK = %d [%d]\n", (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK); return 0; err1: clk_put(tlv320aic23_mclk); platform_device_del(osk_snd_device); platform_device_put(osk_snd_device); return err; }
/** * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static inline void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { usb_remove_hcd(hcd); if (!IS_ERR_OR_NULL(hcd->phy)) { (void) otg_set_host(hcd->phy->otg, 0); usb_put_phy(hcd->phy); } if (machine_is_omap_osk()) gpio_free(9); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); clk_put(usb_dc_ck); clk_put(usb_host_ck); }
/** * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static inline void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); usb_remove_hcd(hcd); if (ohci->transceiver) { (void) otg_set_host(ohci->transceiver, 0); put_device(ohci->transceiver->dev); } if (machine_is_omap_osk()) omap_free_gpio(9); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); clk_put(usb_dc_ck); clk_put(usb_host_ck); }
/** * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static inline void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { dev_dbg(hcd->self.controller, "stopping USB Controller\n"); usb_remove_hcd(hcd); omap_ohci_clock_power(0); if (!IS_ERR_OR_NULL(hcd->phy)) { (void) otg_set_host(hcd->phy->otg, 0); usb_put_phy(hcd->phy); } if (machine_is_omap_osk()) gpio_free(9); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); clk_put(usb_dc_ck); clk_put(usb_host_ck); }
static void omap_kp_scan_keypad(unsigned char *state) { int col = 0; /* read the keypad status */ omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC); for (col = 0; col < 8; col++) { omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC); if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) { udelay(9); } else { udelay(2); } state[col] = ~omap_readw(OMAP_MPUIO_BASE + OMAP_MPUIO_KBR_LATCH) & 0xff; } omap_writew(0x00, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC); udelay(2); }
/** * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static inline void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); usb_remove_hcd(hcd); if (ohci->transceiver) { (void) otg_set_host(ohci->transceiver, 0); put_device(ohci->transceiver->dev); } #ifndef CONFIG_ARCH_OMAP34XX if (machine_is_omap_osk()) gpio_free(9); #endif iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); #ifndef CONFIG_ARCH_OMAP34XX clk_put(usb_dc_ck); clk_put(usb_host_ck); #endif }
static int ohci_omap_init(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = hcd->self.controller->platform_data; int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { ohci_to_hcd(ohci)->self.otg_port = config->otg; /* */ ohci_to_hcd(ohci)->power_budget = 8; } /* */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_USB_OTG if (need_transceiver) { ohci->transceiver = usb_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver->otg, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(hcd->self.controller, "can't find transceiver\n"); return -ENODEV; } ohci->start_hnp = start_hnp; } #endif omap_ohci_clock_power(1); if (cpu_is_omap15xx()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } if ((ret = ohci_init(ohci)) < 0) return ret; /* */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* */ rh &= ~RH_A_NPS; /* */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* */ omap_cfg_reg(W8_1610_GPIO9); gpio_request(9, "OHCI overcurrent"); gpio_direction_input(9); /* */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); ohci->flags &= ~OHCI_QUIRK_HUB_POWER; } else if (machine_is_nokia770()) { /* */ ohci_to_hcd(ohci)->power_budget = 0; } /* */ omap_ohci_transceiver_power(1); /* */ return 0; }
static int omap_start_hc(struct ohci_hcd *ohci, struct platform_device *pdev) { struct omap_usb_config *config = pdev->dev.platform_data; int need_transceiver = (config->otg != 0); dev_dbg(&pdev->dev, "starting USB Controller\n"); if (config->otg) { ohci->hcd.self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ ohci->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_ARCH_OMAP_OTG if (need_transceiver) { ohci->transceiver = otg_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver, &ohci->hcd.self); dev_dbg(&pdev->dev, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(&pdev->dev, "can't find transceiver\n"); return -ENODEV; } } #endif if (machine_is_omap_osk()) { omap_request_gpio(9); omap_set_gpio_direction(9, 1); omap_set_gpio_dataout(9, 1); } omap_ohci_clock_power(1); omap_ohci_transceiver_power(1); if (cpu_is_omap1510()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
static int ohci_omap_init(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = hcd->self.controller->platform_data; int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { ohci_to_hcd(ohci)->self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ ohci_to_hcd(ohci)->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_ARCH_OMAP_OTG if (need_transceiver) { ohci->transceiver = otg_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(hcd->self.controller, "can't find transceiver\n"); return -ENODEV; } } #endif omap_ohci_clock_power(1); if (cpu_is_omap1510()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } if ((ret = ohci_init(ohci)) < 0) return ret; /* board-specific power switching and overcurrent support */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* power switching (ganged by default) */ rh &= ~RH_A_NPS; /* TPS2045 switch for internal transceiver (port 1) */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* gpio9 for overcurrent detction */ omap_cfg_reg(W8_1610_GPIO9); omap_request_gpio(9); omap_set_gpio_direction(9, 1 /* IN */); /* for paranoia's sake: disable USB.PUEN */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); distrust_firmware = 0; } else if (machine_is_nokia770()) { /* We require a self-powered hub, which should have * plenty of power. */ ohci_to_hcd(ohci)->power_budget = 0; } /* FIXME khubd hub requests should manage power switching */ omap_ohci_transceiver_power(1); /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
static int ohci_omap_reset(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = dev_get_platdata(hcd->self.controller); int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { hcd->self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ hcd->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); /* XXX OMAP16xx only */ if (config->ocpi_enable) config->ocpi_enable(); #ifdef CONFIG_USB_OTG if (need_transceiver) { hcd->phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(hcd->phy)) { int status = otg_set_host(hcd->phy->otg, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s phy, status %d\n", hcd->phy->label, status); if (status) { usb_put_phy(hcd->phy); return status; } } else { dev_err(hcd->self.controller, "can't find phy\n"); return -ENODEV; } ohci->start_hnp = start_hnp; } #endif omap_ohci_clock_power(1); if (cpu_is_omap15xx()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } ret = ohci_setup(hcd); if (ret < 0) return ret; if (config->otg || config->rwc) { ohci->hc_control = OHCI_CTRL_RWC; writel(OHCI_CTRL_RWC, &ohci->regs->control); } /* board-specific power switching and overcurrent support */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* power switching (ganged by default) */ rh &= ~RH_A_NPS; /* TPS2045 switch for internal transceiver (port 1) */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* gpio9 for overcurrent detction */ omap_cfg_reg(W8_1610_GPIO9); gpio_request(9, "OHCI overcurrent"); gpio_direction_input(9); /* for paranoia's sake: disable USB.PUEN */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); ohci->flags &= ~OHCI_QUIRK_HUB_POWER; } else if (machine_is_nokia770()) { /* We require a self-powered hub, which should have * plenty of power. */ ohci_to_hcd(ohci)->power_budget = 0; } /* FIXME khubd hub requests should manage power switching */ omap_ohci_transceiver_power(1); /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }