221
static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
223
if (port < 0 || port >= 2)
226
if (pdata->vbus_pin[port] <= 0)
229
gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable);
232
static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
234
if (port < 0 || port >= 2)
237
if (pdata->vbus_pin[port] <= 0)
240
return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted;
244
* Update the status data from the hub with the over-current indicator change.
246
static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
248
struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
249
int length = ohci_hub_status_data(hcd, buf);
252
for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) {
253
if (pdata->overcurrent_changed[port]) {
256
buf[0] |= 1 << (port + 1);
264
* Look at the control requests to the root hub and see if we need to override.
266
static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
267
u16 wIndex, char *buf, u16 wLength)
269
struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
270
struct usb_hub_descriptor *desc;
272
u32 *data = (u32 *)buf;
274
dev_dbg(hcd->self.controller,
275
"ohci_at91_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n",
276
hcd, typeReq, wValue, wIndex, buf, wLength);
280
if (wValue == USB_PORT_FEAT_POWER) {
281
dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n");
282
ohci_at91_usb_set_power(pdata, wIndex - 1, 1);
287
case ClearPortFeature:
289
case USB_PORT_FEAT_C_OVER_CURRENT:
290
dev_dbg(hcd->self.controller,
291
"ClearPortFeature: C_OVER_CURRENT\n");
293
if (wIndex == 1 || wIndex == 2) {
294
pdata->overcurrent_changed[wIndex-1] = 0;
295
pdata->overcurrent_status[wIndex-1] = 0;
300
case USB_PORT_FEAT_OVER_CURRENT:
301
dev_dbg(hcd->self.controller,
302
"ClearPortFeature: OVER_CURRENT\n");
304
if (wIndex == 1 || wIndex == 2) {
305
pdata->overcurrent_status[wIndex-1] = 0;
310
case USB_PORT_FEAT_POWER:
311
dev_dbg(hcd->self.controller,
312
"ClearPortFeature: POWER\n");
314
if (wIndex == 1 || wIndex == 2) {
315
ohci_at91_usb_set_power(pdata, wIndex - 1, 0);
322
ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
327
case GetHubDescriptor:
329
/* update the hub's descriptor */
331
desc = (struct usb_hub_descriptor *)buf;
333
dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n",
334
desc->wHubCharacteristics);
336
/* remove the old configurations for power-switching, and
337
* over-current protection, and insert our new configuration
340
desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM);
341
desc->wHubCharacteristics |= cpu_to_le16(0x0001);
343
if (pdata->overcurrent_supported) {
344
desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM);
345
desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001);
348
dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n",
349
desc->wHubCharacteristics);
354
/* check port status */
356
dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex);
358
if (wIndex == 1 || wIndex == 2) {
359
if (! ohci_at91_usb_get_power(pdata, wIndex-1)) {
360
*data &= ~cpu_to_le32(RH_PS_PPS);
363
if (pdata->overcurrent_changed[wIndex-1]) {
364
*data |= cpu_to_le32(RH_PS_OCIC);
367
if (pdata->overcurrent_status[wIndex-1]) {
368
*data |= cpu_to_le32(RH_PS_POCI);
226
377
/*-------------------------------------------------------------------------*/
228
379
static const struct hc_driver ohci_at91_hc_driver = {
270
421
/*-------------------------------------------------------------------------*/
423
static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
425
struct platform_device *pdev = data;
426
struct at91_usbh_data *pdata = pdev->dev.platform_data;
429
/* From the GPIO notifying the over-current situation, find
430
* out the corresponding port */
431
gpio = irq_to_gpio(irq);
432
for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) {
433
if (pdata->overcurrent_pin[port] == gpio)
437
if (port == ARRAY_SIZE(pdata->overcurrent_pin)) {
438
dev_err(& pdev->dev, "overcurrent interrupt from unknown GPIO\n");
442
val = gpio_get_value(gpio);
444
/* When notified of an over-current situation, disable power
445
on the corresponding port, and mark this port in
448
ohci_at91_usb_set_power(pdata, port, 0);
449
pdata->overcurrent_status[port] = 1;
450
pdata->overcurrent_changed[port] = 1;
453
dev_dbg(& pdev->dev, "overcurrent situation %s\n",
454
val ? "exited" : "notified");
459
/*-------------------------------------------------------------------------*/
272
461
static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
274
463
struct at91_usbh_data *pdata = pdev->dev.platform_data;
278
/* REVISIT make the driver support per-port power switching,
279
* and also overcurrent detection. Here we assume the ports
280
* are always powered while this driver is active, and use
281
* active-low power switches.
283
467
for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
284
468
if (pdata->vbus_pin[i] <= 0)
286
470
gpio_request(pdata->vbus_pin[i], "ohci_vbus");
287
gpio_direction_output(pdata->vbus_pin[i], 0);
471
ohci_at91_usb_set_power(pdata, i, 1);
474
for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) {
477
if (pdata->overcurrent_pin[i] <= 0)
479
gpio_request(pdata->overcurrent_pin[i], "ohci_overcurrent");
481
ret = request_irq(gpio_to_irq(pdata->overcurrent_pin[i]),
482
ohci_hcd_at91_overcurrent_irq,
483
IRQF_SHARED, "ohci_overcurrent", pdev);
485
gpio_free(pdata->overcurrent_pin[i]);
486
dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n");