98 // it via a charger type observer |
98 // it via a charger type observer |
99 static UsbShai::MChargerDetectorIf* gChargerDetector = NULL; |
99 static UsbShai::MChargerDetectorIf* gChargerDetector = NULL; |
100 |
100 |
101 // Charger observer is the guy who want to monitor the chager type event. |
101 // Charger observer is the guy who want to monitor the chager type event. |
102 static UsbShai::MChargerDetectorObserverIf* gChargerObsever = NULL; |
102 static UsbShai::MChargerDetectorObserverIf* gChargerObsever = NULL; |
|
103 |
|
104 static UsbShai::TChargerDetectorProperties gChargerDetectorProperties; |
103 |
105 |
104 |
106 |
105 // Those const variables are used to construct the default |
107 // Those const variables are used to construct the default |
106 // Usb descriptors, Upper layer can change them later. |
108 // Usb descriptors, Upper layer can change them later. |
107 /** Default vendor ID to set in device descriptor */ |
109 /** Default vendor ID to set in device descriptor */ |
350 EXPORT_C void DUsbClientController::DeviceCaps(const DBase* aClientId, TDes8& aCapsBuf) const |
352 EXPORT_C void DUsbClientController::DeviceCaps(const DBase* aClientId, TDes8& aCapsBuf) const |
351 { |
353 { |
352 __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::DeviceCaps()")); |
354 __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::DeviceCaps()")); |
353 TUsbDeviceCaps caps; |
355 TUsbDeviceCaps caps; |
354 caps().iTotalEndpoints = iDeviceUsableEndpoints; // not DeviceTotalEndpoints()! |
356 caps().iTotalEndpoints = iDeviceUsableEndpoints; // not DeviceTotalEndpoints()! |
|
357 |
|
358 // In the SHAI API, all PSLs are required to support soft connection |
|
359 caps().iConnect = ETrue; |
355 |
360 |
356 caps().iSelfPowered = iSelfPowered; |
361 caps().iSelfPowered = iSelfPowered; |
357 caps().iRemoteWakeup = iRemoteWakeup; |
362 caps().iRemoteWakeup = iRemoteWakeup; |
358 caps().iHighSpeed = (iControllerProperties.iControllerCaps & UsbShai::KDevCapHighSpeed)?ETrue:EFalse; |
363 caps().iHighSpeed = (iControllerProperties.iControllerCaps & UsbShai::KDevCapHighSpeed)?ETrue:EFalse; |
359 |
364 |
400 { |
405 { |
401 TUsbcEndpointInfoArray endpointData = TUsbcEndpointInfoArray(aEndpointData); |
406 TUsbcEndpointInfoArray endpointData = TUsbcEndpointInfoArray(aEndpointData); |
402 return SetInterface(aClientId, aThread, aInterfaceNum, aClass, aString, aTotalEndpointsUsed, |
407 return SetInterface(aClientId, aThread, aInterfaceNum, aClass, aString, aTotalEndpointsUsed, |
403 endpointData, (TInt*) aRealEpNumbers, aFeatureWord); |
408 endpointData, (TInt*) aRealEpNumbers, aFeatureWord); |
404 } |
409 } |
|
410 |
|
411 |
|
412 |
|
413 EXPORT_C void DUsbClientController::ChargerDetectorCaps(UsbShai::TChargerDetectorProperties& aProperties) |
|
414 { |
|
415 aProperties = gChargerDetectorProperties; |
|
416 } |
|
417 |
405 |
418 |
406 |
419 |
407 /** Creates a new USB interface (one setting), complete with endpoints, descriptors, etc., |
420 /** Creates a new USB interface (one setting), complete with endpoints, descriptors, etc., |
408 and chains it into the internal device configuration tree. |
421 and chains it into the internal device configuration tree. |
409 |
422 |
921 DeRegisterForStatusChange(aClientId); |
934 DeRegisterForStatusChange(aClientId); |
922 // Cancel all endpoint state notification requests |
935 // Cancel all endpoint state notification requests |
923 DeRegisterForEndpointStatusChange(aClientId); |
936 DeRegisterForEndpointStatusChange(aClientId); |
924 DeRegisterForOtgFeatureChange(aClientId); |
937 DeRegisterForOtgFeatureChange(aClientId); |
925 DeRegisterClientCallback(aClientId); |
938 DeRegisterClientCallback(aClientId); |
|
939 DeRegisterChargingPortTypeNotify(aClientId); |
926 // Delete the interface including all its alternate settings which might exist. |
940 // Delete the interface including all its alternate settings which might exist. |
927 // (If we release the default setting (0), all alternate settings are deleted as well.) |
941 // (If we release the default setting (0), all alternate settings are deleted as well.) |
928 const TInt r = ReleaseInterface(aClientId, 0); |
942 const TInt r = ReleaseInterface(aClientId, 0); |
929 // Cancel all remaining (if any) read/write requests |
943 // Cancel all remaining (if any) read/write requests |
930 DeleteRequestCallbacks(aClientId); |
944 DeleteRequestCallbacks(aClientId); |
2616 } |
2630 } |
2617 |
2631 |
2618 EXPORT_C TInt DUsbClientController::SignalRemoteWakeup() |
2632 EXPORT_C TInt DUsbClientController::SignalRemoteWakeup() |
2619 { |
2633 { |
2620 return iController.SignalRemoteWakeup(); |
2634 return iController.SignalRemoteWakeup(); |
|
2635 } |
|
2636 /** Registers client request for USB charger type notification. Client is notified when USB device is |
|
2637 attached to or detached from any USB charger, and the charger type is sent to client. |
|
2638 |
|
2639 @param aCallback A reference to a properly filled in charger type callback structure. |
|
2640 |
|
2641 @return KErrNone if callback successfully registered, KErrGeneral if this callback is already registered |
|
2642 (it won't be registered twice). |
|
2643 */ |
|
2644 EXPORT_C TInt DUsbClientController::RegisterChargingPortTypeNotify(TUsbcChargerTypeCallback& aCallback) |
|
2645 { |
|
2646 __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RegisterChargingPortTypeNotify()")); |
|
2647 if (iChargerTypeCallbacks.Elements() == KUsbcMaxListLength) |
|
2648 { |
|
2649 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: In charger type list, the maximum list length reached: %d", |
|
2650 KUsbcMaxListLength)); |
|
2651 return KErrGeneral; |
|
2652 } |
|
2653 if (IsInTheChargerTypeList(aCallback)) |
|
2654 { |
|
2655 __KTRACE_OPT(KUSB, Kern::Printf(" Error: UsbcChargerTypeCallback @ 0x%x already registered", &aCallback)); |
|
2656 return KErrGeneral; |
|
2657 } |
|
2658 const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock); |
|
2659 iChargerTypeCallbacks.AddLast(aCallback); |
|
2660 __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq); |
|
2661 |
|
2662 if(iCurrentChargerType != UsbShai::EPortTypeNone) |
|
2663 { |
|
2664 aCallback.SetChargerType(iCurrentChargerType); |
|
2665 aCallback.SetPendingNotify(ETrue); |
|
2666 } |
|
2667 return KErrNone; |
|
2668 } |
|
2669 |
|
2670 /** De-registers (removes from the list of pending requests) a notification callback for |
|
2671 USB charger type change. |
|
2672 |
|
2673 @param aClientId A pointer to the LDD owning the charger type callback. |
|
2674 |
|
2675 @return KErrNone if callback successfully unregistered, KErrNotFound if the callback couldn't be found. |
|
2676 */ |
|
2677 EXPORT_C TInt DUsbClientController::DeRegisterChargingPortTypeNotify(const DBase* aClientId) |
|
2678 { |
|
2679 __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterChargingPortTypeNotify()")); |
|
2680 __ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__)); |
|
2681 const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock); |
|
2682 TSglQueIter<TUsbcChargerTypeCallback> iter(iChargerTypeCallbacks); |
|
2683 TUsbcChargerTypeCallback* p; |
|
2684 while ((p = iter++) != NULL) |
|
2685 { |
|
2686 if (p->Owner() == aClientId) |
|
2687 { |
|
2688 __KTRACE_OPT(KUSB, Kern::Printf(" removing UsbcChargerTypeCallback @ 0x%x", p)); |
|
2689 iChargerTypeCallbacks.Remove(*p); |
|
2690 __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq); |
|
2691 return KErrNone; |
|
2692 } |
|
2693 } |
|
2694 __KTRACE_OPT(KUSB, Kern::Printf(" client not found")); |
|
2695 __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq); |
|
2696 return KErrNotFound; |
2621 } |
2697 } |
2622 |
2698 |
2623 EXPORT_C TBool DUsbClientController::CurrentlyUsingHighSpeed() |
2699 EXPORT_C TBool DUsbClientController::CurrentlyUsingHighSpeed() |
2624 { |
2700 { |
2625 UsbShai::TSpeed speed = iController.DeviceOperatingSpeed(); |
2701 UsbShai::TSpeed speed = iController.DeviceOperatingSpeed(); |
2911 iStackIsActive(EFalse), |
2987 iStackIsActive(EFalse), |
2912 iClientSupportReady(EFalse), |
2988 iClientSupportReady(EFalse), |
2913 iUsbResetDeferred(EFalse), |
2989 iUsbResetDeferred(EFalse), |
2914 iEnablePullUpOnDPlus(NULL), |
2990 iEnablePullUpOnDPlus(NULL), |
2915 iDisablePullUpOnDPlus(NULL), |
2991 iDisablePullUpOnDPlus(NULL), |
2916 iOtgContext(NULL) |
2992 iOtgContext(NULL), |
|
2993 iChargerTypeCallbacks(_FOFF(TUsbcChargerTypeCallback, iLink)), |
|
2994 iCurrentChargerType(UsbShai::EPortTypeNone) |
2917 { |
2995 { |
2918 __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DUsbClientController()")); |
2996 __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DUsbClientController()")); |
2919 |
2997 |
|
2998 // Note that we take a direct copy of the controller properties in |
|
2999 // the initialization list for now. If fields are later added to |
|
3000 // the properties class in the SHAI, we need to start copying |
|
3001 // field-by-field and check the PSL reported capabilities before |
|
3002 // accessing a field that may not be present in an older PSL |
|
3003 // binary. |
|
3004 |
2920 iLastError = KErrNone; |
3005 iLastError = KErrNone; |
2921 |
3006 |
2922 #ifndef SEPARATE_USB_DFC_QUEUE |
3007 #ifndef SEPARATE_USB_DFC_QUEUE |
2923 iPowerUpDfc.SetDfcQ(Kern::DfcQue0()); |
3008 iPowerUpDfc.SetDfcQ(Kern::DfcQue0()); |
2924 iPowerDownDfc.SetDfcQ(Kern::DfcQue0()); |
3009 iPowerDownDfc.SetDfcQ(Kern::DfcQue0()); |
4685 } |
4770 } |
4686 |
4771 |
4687 // Functions from UsbShai::MChargerDetectorObserverIf |
4772 // Functions from UsbShai::MChargerDetectorObserverIf |
4688 void DUsbClientController::NotifyPortType(UsbShai::TPortType aPortType) |
4773 void DUsbClientController::NotifyPortType(UsbShai::TPortType aPortType) |
4689 { |
4774 { |
4690 // FIXME: Not yet implemented! |
4775 __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::NotifyPortType(), aPortType = %d", aPortType)); |
|
4776 |
|
4777 TSglQueIter<TUsbcChargerTypeCallback> iter(iChargerTypeCallbacks); |
|
4778 TUsbcChargerTypeCallback* p; |
|
4779 |
|
4780 iCurrentChargerType = aPortType; |
|
4781 |
|
4782 while ((p = iter++) != NULL) |
|
4783 { |
|
4784 p->SetChargerType(aPortType); |
|
4785 p->DoCallback(); |
|
4786 } |
4691 } |
4787 } |
4692 |
4788 |
4693 void DUsbClientController::Buffer2Setup(const TAny* aBuf, TUsbcSetup& aSetup) const |
4789 void DUsbClientController::Buffer2Setup(const TAny* aBuf, TUsbcSetup& aSetup) const |
4694 { |
4790 { |
4695 // TUint8 index |
4791 // TUint8 index |
4816 // Only on charger detector is allowed per system. |
4912 // Only on charger detector is allowed per system. |
4817 if( gChargerDetector != NULL) |
4913 if( gChargerDetector != NULL) |
4818 { |
4914 { |
4819 return ; |
4915 return ; |
4820 } |
4916 } |
4821 |
4917 |
|
4918 // We take a direct copy of the charger detector properties for |
|
4919 // now. If fields are later added to the properties classes in the |
|
4920 // SHAI, we need to start copying field-by-field and check the PSL |
|
4921 // reported capabilities before accessing a field that may not be |
|
4922 // present in an older PSL binary. |
4822 gChargerDetector = &aChargerDetector; |
4923 gChargerDetector = &aChargerDetector; |
|
4924 gChargerDetectorProperties = aProperties; |
4823 |
4925 |
4824 if(gChargerObsever != NULL) |
4926 if(gChargerObsever != NULL) |
4825 { |
4927 { |
4826 // Register to charger detector to listen to any charger type change |
4928 // Register to charger detector to listen to any charger type change |
4827 // events. |
4929 // events. |