6/22/2012

qualcomm msm7227 Audio device flow in Android part

Reagrding audio device flow, we can find some document for AMSS such as 80-VH828-1.

However, there is few code flow document for MSM7227 Android regarding device handling. Here shows device code flow in Android part.



Brief flow fordevice is "Application --> Libaudio --> qdsp5 --> QDSP or AMSS(ARM9)"



There are four parts for device handling.

1) Audio routing : do_routing / Android

2) Audio Tuning : AudioFilter.csv / Android

3) Voice Tuning : voccal.c / AMSS

4) ADIE setting : msm_aud.h / AMSS



Android source is starting from 'do_routing' in AudioHardware.cpp

There are two paths in audio routing function. One is for ADSP and the other is for AMSS.



* ADSP path

1) msm72xx_enable_audpp() : open device 'msm_pcm_ctl' to handle AFE

sending filter parameters through ioctl().

2) audpp_ioctl in /qdsp5/audio_out.c : msms_adsp_write() is sending audio filter parameters.

ex) MBADRC setting is called by audpp_dsp_set_mbadrc().



* AMSS path

1) doAudioRouteOrMute() : open device 'msm_snd' to handle AFE

do_route_audio_rpc() is sending routing parameter through ioctl for RPC.

2) snd_ioctl in qdsp5/snd.c : msms_rpc_call is called to send the paramters to AMSS

ex) SND DEVICE

volume table, ADIE configuration is defined in AMSS with SND_DEVICE id from Android.

HSUSB related NV items in qualcomm chipset

NV Items defined by HS-USB

High Speed USB Current Composition

a.. Number: 04526
b.. Area: System
c.. Description: USB Composition value
HS USB Remote Wakeup Delay

a.. Number: 04918
b.. Area: System
c.. Description:
a.. Indicates the number of milliseconds to wait before performing explicit remote wakeup when in suspend mode. When set to 0, the device doesn't perform explicit remote wakeup.
b.. Default (inactive) is 0.
c.. Set to 3000 before running USBCV.
HS USB Use PMIC OTG comparators

a.. Number: 06235
b.. Area: System
c.. Description:
a.. Indicates whether to use PMIC comparators in LCU.
b.. Default (inactive) is FALSE.
HS USB Number of SDCC LUNS

a.. Number: 06239
b.. Area: System
c.. Description:
a.. Indicates the number of SDCC/MMC LUNs that are enabled. The actual number of MS LUNS will be the maximum of this value and the actual number of SDCC controllers defined by the target.
b.. Default (inactive) is 1.
Host Mode Enabled

a.. Number: 06259
b.. Area: System
c.. Description:
a.. 0x01 means host mode is enabled. 0x00 means host mode is disabled.
b.. Default (inactive) is 0x00.
HS USB Use Diag on Legacy Port

a.. Number: 05044
b.. Area: System
c.. Description:
a.. Indicates whether DIAG should run over HS-USB or (if available) FS-USB (legacy). If full-speed device support is disabled in the target, this NV item is not being used.
b.. Default (inactive) is FALSE.
HS-USB disable sleep voting

a.. Number: 06327
b.. Area: System
c.. Description
a.. Indicates whether to disable voting for sleep when entering LPM after the USB bus is suspended.
b.. This NV item does not affect sleep voting when the USB port is disconnected. Sleep voting is always enabled in this case.
a.. 1 - Disable sleep voting during USB bus suspend state.
b.. 0 - Sleep voting is enabled during USB bus suspend state (default).
Set HS USB performance

a.. Name: NV_HS_USB_PERFORMANCE_SETTING_I
b.. Number: 6841
c.. Area: System
d.. Description:
a.. Determine HS USB performance
a.. LOW = 0 - minimum speed : CPU MIPS will be voted with 0 for NPA. This is only for a testing purpose because it does not guarantee the 4 MHz minimum PCLK requirement for HS USB link HW.
b.. MID = 1 - medium speed
c.. HIGH = 2 - maximum speed
Disable LPM

a.. Number: 6843
b.. Area: System
c.. Description:
a.. Indicates whether phone will enter LPM (low power mode)or not
a.. 0 - LPM is enabled
b.. 1 - LPM is disabled.
a.. By default LPM is enabled.
b.. Note - Disabling LPM also disables HS-USB sleep voting.
PHY Configuration

a.. Number: 06872
b.. Area: System
c.. Description:
a.. change the PHY configuration parameters
a.. pre_emphasis_enable - enable/disable pre-emphasis configure.
b.. pre_emphasis_value - the value for pre-emphasis.
c.. amplitude_adjustment_enable - enable/disable amplitude adjustment.
d.. amplitude_adjustment_value - the value for amplitude adjustment.


External NV Items useful to HS-USB

USB Charging NV Disable Value

a.. Number: 02822
b.. Area: Factory
c.. Description:
a.. Indicates to PMIC charging software whether to use USB charging. When set to 0, USB charging is enabled. When set to 1, USB charging is disabled.
b.. Default (inactive) is handled as charging disabled.
RMNet Autoconnect

a.. Number: 03534
b.. Area: Data
c.. Description:
a.. Indicates whether RMNet will automatically start the data call after the USB ECM connection is established.
a.. FALSE - Don't use RMNet autoconnect.
b.. TRUE - Use RMNet autoconnect.
a.. Default (inactive) is FALSE.
UIM First Instruction Class

a.. Number: 00896
b.. Area: GSM
c.. Description:
a.. Indicates whether to use UICC:
a.. 0-1 Don't use UICC
b.. 2 Use UICC without ISO Reset line high workaround
c.. 3 Use UICC with ISO Reset line high workaround
a.. Default (inactive) is 2.
Application Power Disable

a.. Number: 04201
b.. Area: Debug
c.. Description:
a.. Indicates whether to disable power on application processor (apps power collapse). Prerequisite to TCXO shutdown.
a.. FALSE - Use apps power collapse.
b.. TRUE - Don't use apps power collapse.
DCVS Application NV

a.. Number: 04393
b.. Area: System
c.. Description:
a.. Indicates whether to disable CPU clock control.
a.. type = 0 - Disable DCVS.
b.. type = 1 - Enable DCVS.
Enable reset logging

a.. Number: 04399
b.. Area: Debug
c.. Description:
a.. Indicates whether Phone will go to download mode after reset
a.. type = 0 - Disable the move to sw dload..
b.. type = 1 - Enable the move to sw dload.

I2C Power collapse issue in android build

Problem: The modem side processor keeps spinning for the spinlock acquired by the apps side processor for an I2C transaction when the apps side processor is power collapsed.



Solution:

As a solution to this, wakelocks can be used. "Wakelock" is a mechanism which can prevent the system from going into a low-power state.



To prevent the above mentioned problem, the I2C driver at the apps side grabs a wakelock at the beginning of the I2C transaction (inside the msm_i2c_xfer() and then releases it at the end of the transaction. With this, the power collapse is delayed for the time the wakelock is held by the i2c driver i.e. till the spinlock held by the apps side processor is released, and the released spinlock can, then, be used by the modem side processor.



To setup a wakelock in the kernel space:

#include <linux/wakelock.h>

wake_lock_init(struct wake_lock *lock, int type, const char *name)

where,

name: name of the lock

type: kind of wakelock



The two types are : WAKE_LOCK_SUSPEND : prevents the system from suspending

WAKE_LOCK_IDLE: prevents going into a low_power idle state



Following are the APIs to handle this lock:



void wake_lock(struct wake_lock *lock);

void wake_lock_timeout(struct wake_lock *lock, long timeout);

void wake_unlock(struct wake_lock *lock);



Note: pm_qos() is not intended to influence the suspend power collapse. It influences the idle power collapse. Thus, pm_qos() should not be used in the above mentioned scenario.

I2C Suspend Power Collapse in AMSS 8650 Software

Problem: The modem side processor keeps spinning for the spinlock acquired by the apps side processor for an I2C transaction when the apps side processor is suspend power collapsed.



Solution: The interrupts should be enabled before calling I2C on the Apps side.



Suspend() is already using a mutex_lock (which is also being used for the I2C transaction) which makes sure that the transaction is over before suspend happens. So, suspend power collapse should not happen until ongoing I2C transaction is done. And once suspend is called, any further I2C transaction cannot even acquire remote lock.



In such a situation, one should check that the interrupts are enabled when an I2C transaction on the apps side is being initiated. If the interrupts are disabled, then the driver cannot finish the transaction since the driver is interrupt driven and the lock acquired is never released. Thus, the interrupts should be enabled before calling I2C on the Apps side.

If Host PC do not set DTR high on rmnet interface, how to set it to high by default in AMSS

Question: If Host PC do not set DTR high on rmnet interface, how to set it to high by default in AMSS.
Detail:A2 Rmnet interface depends on DTR high signal, it do not work if DTR low. In standard USB ECM driver(Linux/Mac), there is no operation for setting DTR in host driver side, so we call invoke_app_enable_disable_cbs directly in hsu_al_ecm_enabled_cb.



if (hsu_al_ecm_is_standard)

{

invoke_app_enable_disable_cbs(context_ptr);

}



When customer refer to ECM to implement QC rmnet driver in Linux/Mac, they are likely not set DTR high, thus invoke_app_enable_disable_cbs will never be called in hsu_al_ecm_set_control_line_state_cb.




BTW, when it's not set, MDM9200 could have problem like receive "1" byte no matter how long data packet is sent from host side.



Answer:

We could add a line in the end of hsu_al_ecm_enabled_cb.

hsu_al_ecm_set_control_line_state_cb(1, ctx).



Then it will be called when modem get SET_CONFIGURATION command during enumeration.

It's also a good idea to suggest customer add SET_DTR high command in host driver side.

In CATC USB analyser log file, USB reset signal is not shown during HS mode

Issue: When using Lecroy's CATC USB log analyzer, Reset signal is not shown correctly during HS mode operation.



Cause: HS mode idle signal electric characteristic is same as SE0.

If the device is being reset from a non-suspended high-speed state, then the device must wait no less than 3.0 ms and no more than 3.125 ms (TWTREV) before reverting to full-speed.

Reversion to fullspeed is accomplished by removing the high-speed termination and reconnecting the D+ pull-up
resistor.

The device samples the bus state, and checks for SE0 (reset as opposed to suspend), no less than 100 μs and no more than 875 μs (TWTRSTHS) after starting reversion to full-speed.

If SE0 (reset) is detected, then the device begins a high-speed detection handshake



Solution: Instead of reset packet, Chirp signal can be used for detecting reset signal. Because chirp signal always happen when HSUSB capable device get reset signal. So we can assume that reset signal happens when chirp packet is shown in CATC usb log file.

Instead of TCXO_EN, can any GPIO be used for controlling USB clock buffer (NAND gate)?

Question :

As seeing Reference schematic for all the MSMs which are supporting HS-USB by using internal HS-USB PHY circuit, TCXO_EN signal is used for enable signal of NAND gate for USB clock. But USB clock is usually not required when USB block is not operating without USB cable inserted.

So to reduce leakage current on this NAND gate and control USB clock properly at this case, can any GPIO instead of TCXO_EN be used for enable signal of this NAND gate?



Answer :

No. TCXO_EN should be used for this. Basically, USB clock should be supplied during normal operation even when USB is not operating including suspend mode, in order to meet USB 2.0 specification requirement for HS-USB enumeration time.

In addition, in case of using normal GPIO, sleep current actually increases to more than 1mA from both VREG_MSMC & VREG_MSMA due to feedback nature of the external NAND circuit when TCXO was no longer supplied.

Is Gadget frame work supported and how to enable Gadget framework?

Q) Is gadget framework supported on Android Eclair?
Ans) Yes, Gadget framework is supported on the Android éclair



Q) How to check whether Gadget framework is enabled or not?

Ans) There are two frameworks for USB device driver in Android. One is Gadget framework and the other is Function framework.

Android Cupcake and Donut baselines use Function framework.



Android éclair have Gadget framework enabled by default. OEMs can check the below flags for their reference.

If gadget frame is enabled following flags are defined in the .config file of the chipset.

1) USB_MSM_OTG_72K(Device Drivers-> USB support -> OTG Support for Qualcomm On-chip USB controller).

2) CONFIG_USB_GADGET(Drivers-> USB support -> USB Gadget support ).

3) USB_GADGET_MSM_72K(Drivers-> USB support -> USB Gadget support -> USB peripheral Controller as MSM 72k USB controller).

4) CONFIG_USB_ANDROID(Drivers-> USB support -> USB Gadget support -> USB Gadget Drivers as Android Gadget).

5) CONFIG_USB_ANDROID_DIAG (select Diag function driver).

6) CONFIG_USB_ANDROID_CDC_ECM

7) CONFIG_USB_F_SERIAL

8) CONFIG_MODEM_SUPPORT

9) CONFIG_USB_CSW_HACK



Note: If gadget frame work is enabled, function frame work should to be disabled. Please check that flag CONFIG_USB_FUNCTION undefined or not.

Go to Device Drivers-> USB support -> USB Function support -> [ ] Support for USB Function drivers.(Exclude this)

Exclude this option in the kernelconfig.

Is it possible to use UART1DM and UART1 simultaneously on MSM7x27a?

Q) Is it possible to use UART1DM and UART1 simultaneously on MSM7x27a?





Ans) OEMS wants to use UART1DM and UART1 cores simultaneously and wants to support the below

-- Configuring GPIO [43 - 46] --> as UART1DM (high speed) for Bluetooth.

-- And GPIO [122 - 123] --> as UART1 for debug.



The above is feasible. However, the bit 3 (UART1_RX_SEL) of TLMM_SPARE_WR register should be set to 1 for configuring UART1_RX to GPIO_122.

UART1DM and UART1 are different UART cores in the MSM7x27a chipset and there is no GPIO conflict exists for these cores. Please refer to the Software interface manual for UART1DM core address(0x A020 0000) and UART1 core address(0xa9a00000)



With the above setting, the simultaneous operation of UART1DM and UART1 (on GPIO122,123) can be accomplished.

Also OEMS need to select functionality UART1_TX on GPIO_123, the correct alternate functionality need to be selected in the GPIO_CFG.



Note:- 1) It is not possible to enable the HW flow control on the UART1 if OEMS are using the both UART1DM and UART1 simultaneously.

2) On MSM7x27 chipset both cores can be used simultaneously, as there is GPIO conflict between UART1DM and UART1 cores.

Kernel Panic when enabling USB Tethering on msm7x27

In Froyo Almond builds Kernel Panic was observed when we enable USB Tethering.

Call stack of the crash looks like this :-

PC: strlen+0xc0/0x20
LR: rndis_msg_parser+0x614/0x10c8
Strlen+0xc/0x20
Rndis_msg_parser+0x640/0x10c8
Rndis_command_complete+0x20
Ep0_queue_ack_complete+0x68
Usb_interrupt+0x7f8/0x914
Handle_IRQ_event+0x34/0xf4
Handle_level_iqr+0xd4/0x178
Asm_do_IRQ+0x68/0x84

After collecting Le-Croy log it was found that when RNDIS Host driver sends REMOTE_NDIS_QUERY_MSG for OID_GEN_VENDOR_DESCRIPTION_MSG kernel panic is observed.

Analysis:

Basically crash happens when rndis_msg_parser() gets called for REMOTE_NDIS_QUERY_MSG which further calls rndis_query_response() ->gen_ndis_query_resp(case: OID_GEN_VENDOR_DESCRIPTION)-> which calls strlen (rndis_per_dev_params [configNr].vendorDescr); and we see crash after that.It is found that rndis_set_param_vendor() is setting the value for vendorDescr and vendorId.rndis_set_param_vendor() needs to be called from rndis_bind()[f_rndis.c].

If you see this function being commented out in rndis_bind() like this :-

#if 0
// FIXME
if (rndis_set_param_vendor(rndis->config, vendorID,
manufacturer))
goto fail0;

Qualcomm Universal serial (QUP) on msm7x30 overview.

The Qualcomm Universal serial engine provides a common data path that supports multiple mini cores like i2c , spi etc.
On 7x30 The QUP core has only i2c mini core in it.
Gpio numbers are 16, 17
The output FIFO size is 512 bytes while the input FIFO size is 64 bytes.
The QUP supports 3 I/o modes FIFO, block and data mover mode.
In FIFO mode interrupt is triggered whenever output fifo is empty, or when input fifo has some data.
In Block mode software periodically reads or writes a block of data
In Dmov mode , the DM engine communicates with FIFO to read or write data.


Software currrently has no support for dmov mode.


The data provided to the QUP FIFO, should be "tagged". A tag is a special control byte that is interpreted by QUP to understand what control signals to send the mini core.


For read transactions , the QUp appends a tag to every incoming byte.


For greater detail on How the QUP operaters refer to DCN 80-N0411-1 A

How to enable Analog audio over HS USB port on Qualcomm Android?

Q) could you provide the details about FEATURE_HS_USB_ANALOG_AUDIO? (Or)

Q) How to enable Analog audio over HS USB port?



Ans) If OEM enabled HS-USB feature "FEATURE_HS_USB_ANALOG_AUDIO" in the build, it will provide anhsu_analog_audio_config() API(in Hsu_analog_audio.c file) for switching between the normal USB mode(for data transmission) and one of the supported Analog Audio configurations. When switching to Analog audio mode USB PHY will be disconnected from D+/D- and ID lines and enter Low Power mode.



In the Analog Audio mode, audio can be routed in one of the following ways:


Please look in to hsu_analog_audio_config_phy_to_mode() function(in Hsu_analog_audio.c)for all the supported modes.


Stereo speaker : Left speaker D-, Right speaker D+( HSU_AUDIO_MODE_STEREO_SPK).

Stereo speaker & Mic : Left speaker D-, Right speaker D+, Mic over ID(HSU_AUDIO_MODE_STEREO_SPK_MIC).

Mono speaker : Left speaker D-, Right speaker D+( HSU_AUDIO_MODE_MONO_SPK).

Mono speaker & Mic : Speaker D-, Mic D+( HSU_AUDIO_MODE_MONO_SPK_MIC).



If OEM switch HS USB mode for normal USB operation from analog audio, the USB PHY will be reconnected.



OEM can add their code in below API for USB headset detection:

otg_notify_b_peripheral_state_transition_cb ( otg_appctx_t appctx ) in Hsu_otg_app.c file

The above callback is called by the USB stack when Vbus raised above B-Device Session Valid threshold, OEM can add their code to check headset detection and to switch analog audio mode.



Note: For electrical specification and software register settings OEM's can refer to doc 80-VM151-11.

QPST configuration window can not find the phone.

Q) Why configuration window can not find the phone while the DIAG COM port is available in the device manager?
A) The phone is connected to the PC. But the connectivity in the phone is not completed to the DIAG task.

Details:
When DIAG port is available in the device manager, USB DIAG port enumeration is successful.
To find the phone QPST sends certain DIAG commands.
If DIAG does not response, QPST will assume there is no phone available and display "No Phone".

The most likely reason for this is that DIAG service may be mapped to NULL port in the device.
Please check whether port is mapped or not with rdm_current_device_map[] array.
rdm_current_device_map[RDM_USB_DIAG_DEV] = RDM_DAIG_SRVC;

Q&A about Qualcomm's Windows host driver

Question about Qualcomm usb host driver:


Where can I get the host driver source code

Is there document for Qualcomm's usb Windows host driver

How shall I build the host driver source code?

How can I debug the usb host driver?

Can we use third party's Modem driver?

Does Qualcomm provide usb driver for MAC machine?

Does Qualcomm provide usb driver for Linux machine?

Does Qualcomm's usb driver support Windows2000?

Does Qualcomm's usb driver support Windows Vista?

Does Qualcomm's usb driver support 64bit machine?

How can I get host driver logs?

Do we need another driver for USB2.0 high speed?




Answer


Download

The Qualcomm's usb host driver source code can be downloaded from:

http://support.cdmatech.com/

The path is:

Documents and downloads\library\software tools\sw\USB host driver\release\

There are three packages with different version.

For example:

USB_WIN2KXP2053: Modem/virtual serial port driver

USBWWAN_WINXP1029: NDIS driver

QMICM1400: QMI client for NDIS driver

The number means the version number, please always get the latest version.

All these are source code, provide as reference code, not commercial code.




Document

For modem driver, please see document 80-V4609-1 and 80-VA444-1

For NDIS driver, please see document 80-VB717-1

Please always try to get the latest version for these documents.

Platform support

Qualcomm's usb host driver only support Windows.

Modem driver support Windows2000, XP, Vista, WindowsServer2003, include 64bit version OS.

NDIS driver does not support Windows2000, other is same as modem driver.

For MAC support, OEM need to do themselves, there are some sample code available on the internet.

For Linux support, OEM need to do themselves, the Linux's own ACM driver can work with Qualcomm's modem interface, but may need some extra work.

Build

To build the host driver, you need to install Windows DDK, for vista, you need WDK.

http://www.microsoft.com/whdc/driver/foundation/WhichDDK.mspx

There are script file in the source packet for build.

Please also check the readme in source package.

blddrv.bat is build scripts.

qcpl.bat is the scripts called by blddrv.bat, please check whether the path for DDK in this file match where your DDK installed at.


Debug

To debug the host driver, you shall learn about windows driver development.

windbg is Microsoft's debug tool, it needs two machine for debugging.

debugview.exe is a tool that can get print message from drivers, you can add print message in the driver. You need to build a check version driver to get print message, also need to set Windows register value to enable different level of message.

Please 80-v4609-1 for more.

Version

The host driver source code will keep update with bug fix, enhancement and new feature. Generally, it will keep compatible with previous amss release.

For USB2.0 high speed support, the driver is same, but has a minimal version requirement.

Always try to use the latest driver or as new as possible.

Andoird Platform doesn't go to suspend when BT is on

On LE build or Android build, some of BT chip (not one from Qualcomm) prevents system from getting into suspend. Reason for that could be continuous sending data to MSM or QSD over UART or clock enablement and wake lock holding. To work around this without changing BT solution, platform suspend and resume can be implemented within HSUART driver.


static int msm_hs_suspend(struct platform_device *pdev)
{
struct msm_hs_port *msm_uport;
struct uart_port *uport;


msm_uport = &q_uart_port[pdev->id];
uport = msm_uport->uport;


clk_disable(msm_uport->clk);
msm_uport->clk_state = MSM_HS_CLK_OFF;


disable_irq_wake(uport->irq);
wake_unlock(&rx->wake_lock);


return 0;
}


static int msm_hs_resume(struct platform_device *pdev)
{
struct msm_hs_port *msm_uport;
struct uart_port *uport;


msm_uport = &q_uart_port[pdev->id];
uport = msm_uport->uport;


enable_irq_wake(uport->irq);
msm_hs_request_clock_on(uport);


return 0;
}


This can be applied to 2.6.27 kernel and 2.6.29 kernel for LE and Android build.

Lower SPI transaction rates supported by our driver on qualcomm msm7x30

Question: Are the lower SPI transaction rates supported by our driver and controller ?



Answer: Yes, the hardware supports the lower frequencies. The software also supports it with some modifications. Entries for the new frequencies need to be added to the file clkrgm_bsp_7630.c and enums also need to be added to new plans to the file clkrgm_bsp.h (clkrgm_spi_speed_type). And then, a clean compile needs to be done as the file clkrgm_bsp_7630.c is used by bootloader, AMSS, and Apps.



For the support of the lower frequencies, the number of retries (SPI_NUM_RETRIES) within which the SPI state should become valid should also be increased.



Eg.: If the SPI transaction should take place at a frequency of 185kHz, then this frequency should be added to the list of frequencies for SPI configurations in the file clkrgm_bsp_7630.c located at AMSS/products/7x30/core/systemdrivers/clkregim/src/common/


Here is a snippet:

[CLKRGM_SPI_SPEED_0_185_MHZ] =
{
.freq_hz = 185 * 1000,
.hal_cfg.eSource = HAL_CLK_SOURCE_TCXO,
.hal_cfg.nDivider = 1,
.hal_cfg.nM = 1,
.hal_cfg.nN = 104,
.hal_cfg.n2D = 104
},




Also, this frequency should be added to the file clkrgm_bsp.h as an enum of type clkrgm_spi_speed_type. Here is a snippet:

typedef enum
{ CLKRGM_SPI_SPEED_0_185_MHZ
CLKRGM_SPI_SPEED_10_MHZ,
CLKRGM_SPI_SPEED_26_MHZ,
CLKRGM_SPI_NUM_SPEEDS,
CLKRGM_ENUM_32BITS(SPI_SPEED)
} clkrgm_spi_speed_type;The SPI_NUM_RETRIES (defined in the driver file) should be increased to a bigger value, eg. 2000 considering the lower SPI transaction rates. #define SPI_NUM_RETRIES 2000

How to mount the FAT partition as a Mass Storage device in 7x30 Android build?

For 7x30 eMMC builds, the partition.xml defines the partition layout. And some partition can be formatted as FAT partition.
In some use cases, it is needed for some FAT partition to be mounted as Mass Storage device, some users can drag-and-drop files to and from PC the eMMC 's FAT partition.

The following steps are guidelines for how to do it:

1. In Android UI, go to "Qualcomm Setting --> USB Mass Storage" and click for yes.
2. In Android UI, go to "Qualcomm Setting --> USB Composition " and click on "DIAG+MODEM+NMA+MSC"
3. Adb Shell in to Android, and go to "/dev/block/" and do a list to show all partitions on eMMC. You should see "mmcblk0pN", where N is the order of partitions on eMMC. Then identify the designated partition which is FAT format, as an example we assume partition 0 is the FAT partition we need to mount as Mass Storage device.

4. # mkdir /data/fat
5. # mount -t vfat -r -w /dev/block/mmcblk0p1 /data/fat
6. # echo "/dev/block/mmcblk0p1" > /sys/devices/platform/msm_hsusb/gadget/lun0/file

7. Then unplug and re-plug the device to PC, and you should see eMMC FAT partition from PC

How to make usb host driver work in Vista64

OEM may find load the usb host driver in Vista64 failed, this is because for Vista 64, driver signature is mandatory.

In development phase, we can use a test signature and load driver in vista test mode.

To run Vista in test mode:

1}. Start--->All Programs--->Accessories--->Right Hit "Command Prompt"--->Run as administrator

2). Input this command "Bcdedit �set testsigning ON"

3)Restart Vista, then vista run in test mode


To make a test signature for the driver

1. open certmgr.exe, and remove all the cert for USBHostDriver in root and trustedpublisher you already installed.
2. makecert -r -pe -ss trustedpublisher -n CN=USBHostDriver(Test002) qcusbtest.cer
you get a qcusbtest.cer
3.Certmgr.exe -add qcusbtest.cer -s -r localMachine root
4.Certmgr.exe -add qcusbtest.cer -s -r localMachine trustedpublisher
5. makecat qcusbnet.cdf to get qcusbcer.cat
6.SignTool sign /v /s trustedpublisher /n USBHostDriver(Test002) /t http://timestamp.verisign.com/scripts/timstamp.dll qcusbnet.cat
Now you get a signed cat file, you can verify it with signtool.
7. entry Vista test mode, reboot and install the driver.


For more details, please refer to Windows WDK document

How to make the device able to sleep when usb cable is connected with PC

Only if usb in suspend status, device can sleep with usb cable connected

In sleep task, it will check votes from usb, if usb does not allow to turn off TXCO, the device can not go to deep sleep.
When the usb cable connect to PC, usb task will not vote for deep sleep unless the usb core go to suspend status.

There are some scenarios that the usb core can get suspend event:
1. The host remove the usb device in device manager.
2. The host disable the driver of the usb device
3. The host go to standby mode
4. The host enable selective suspension and there is no activity on usb bus after the set timeout value.

In AMSS, the usb code can get a interrupt for suspend if the scenario happen.
please see 80-v4609-1 about enable selective suspension in Windows.

How to make mass-storage recognized as CD-ROM drive.

Many customer asked how to make their mass-storage device recognized as CD-ROM drive.

It can be done by setting the value of device type for the response of "INQUIRY" request from Host.



Set the value in vget_desc() function in hsu_al_ms.c file like following



static void vget_desc
(
msfd_appctx_t ctx,
juint8_t vlun,
/* out parameters that need to be filled in by the function */
juint32_t* dev_type,
juint8_t* version,
char** vendor,
char** product,
char** prod_rev
)
{

//Sample implementation


*dev_type = SCSI_DEVICE_CDROM // the value is 0x05

*vendor = "Customer company name";
*product = "customer product name ";
*prod_rev = inquiry_data_prod_rev;

How to Know real speed the usb stack work in

In the structure of fd_desc_t, there is a member :current_speed
When usb enumeration process has finished and host send set configure message, the related function driver will be enabled, and this attribute will include the real speed that is used between the device and host.

The host negotiate with device for the speed, both host and device support high speed, then the device will work in high speed mode, other wise, in full speed mode, each fd will be same on the same hub port.

For your own function driver based on mtp example, you can get it in fd_desc_t structure directly.

For obex, you shall be able to get by cdc_ctx_t.desc.current_speed when hsu_al_ser_obex_enabled is called. but as cdc_ctx_t will not be passed to hsu_al_ser_obex_enabled, you need to do some trick. When obex_init is called, the first paramter cdc_handle_t handle is just the cdc_ctx_t point, so need to store it at some place like it in *ctx. see get_avail_obex_data_slot_for_fd(), you can add a new member in hsu_al_ser_obex_data structure to store the point to cdc_ctx_t structure. you can also just simply store it to a global variable.

How to install device driver for USB2.0 Debug Connection Device for WIN8 debugging

Question: How to install device driver for USB2.0 Debug Connection Device for WIN8 debugging.
Detail:USB2.0 Debug Connection Device is enumerated by windows on Snapdragon, windbg tool use the interface to do kernel debugging. We need to Download and Install "Debugging Tools for Windows" package host computer.


Answer:
Refer to below link for Debugging Tools package.

http://msdn.microsoft.com/en-us/windows/hardware/gg463009.



On the host computer, the USB debug driver might get installed automatically, or we might have to install it manually. To install the driver manually, perform the following steps:

1.. In Device Manager, locate the node that represents your USB 2.0 debug connection device.
2.. In the property pages for that node, choose to update or install the driver.
3.. As you go through the driver installation wizard, navigate to the usb2dbg.inf file in the Debugging Tools for Windows package(in "\Debugging Tools for Windows \usb" directory).
4.. Complete the driver installation wizard.

How OEM can set own PID for dload mode in qualcomm msm7x27/7x30?

Many OEM wants to use their own download tool rather than QPST, and does not want to show Qualcomm PID to Host PC in download mode.



In AMSS mode, the way to change PID, VID is in solution # 5814(How to change vid, pid and some string in descriptor)

Here is the simple way to set OEM PID in dload mode.



So, what OEM can do is calling hsu_al_dload_init_ex() function with setting boolean variable, use_amss_product_id as false, which means using different product ID compared to the one in AMSS code. This hsu_al_dload_init_ex() function calls hsu_al_dload_armprog_start_stack_ex(), and checking the boolean variable, and assign PID to HSU_PRODUCT_ID_NON_AMSS which is defined in hsu_conf_sel_comp_utils.h file


Here is the code change that you can do.

1. Modify hsu_al_dload.c file like this:
From:
void hsu_al_dload_init(void)
{
hsu_al_dload_init_ex(TRUE);
}
To:
void hsu_al_dload_init(void)
{
hsu_al_dload_init_ex(FALSE);
}

2. Modify hsu_conf_sel_comp_utils.h file:
From:
/*
* A product ID used for download into RAM in the U2 target.
* This is intended to ensure that the device gets a different
* port number when performing download into RAM than when running
* AMSS.
* This product ID always uses the single interface configuration.
*/
#define HSU_PRODUCT_ID_NON_AMSS 0x9008

To
#define HSU_PRODUCT_ID_NON_AMSS 0x1234 //Customer defined PID.

How the usb function device exist in android/LE build

Question:
How the usb function device exist in android/LE build, how can I find them?

Answer:
There are different device node exist for different usb function.

The usb function code and qualcomm controller driver is at linux kernel driver/usb/function
1. modem /dev/ttyHSUSB0
2. nmea /dev/ttyHSUSB1
3. diag usb diag does not create device node
the character device ddrivers/char/diag/ will create a diag device and sysfs entry sys/devices/virtual/diag/diag
4. adb
two MISC device will be crated
/dev/android_adb
/dev/android_adb_enable
5.mass_storage
Does not need a device node, it has a sysfs entry at /sys/devices/platform/usb_mass_storage

How to add another usb COM port in android/LE build?

Question:
How to add another usb COM port in android/LE build? I need another port for AT command

Answer:
You can modify serial.c in drivers/usb/function to add another tty instance and also modify board-xxx.c to add a usb function.

Detail:
change in serial.c
1. Change "instances=2", to "instance=MAX_INSTANCES", and change MAX_INSTANCES to 3
2. Add a new member in char *a[] = {"modem", "nmea"}
3. Change usb_function_serial[2] to usb_function_serial[MAX_INSTANCES]

change in board-xxxx.c(i.e. board-halibut.c for 7200a, board-7x27.c for 7x27),
1. add a new function map in usb_functions_map[]
2. add a new product_id for your new composition in usb_func_composition[] and set the bit for your new serial port.

Then you can see a new /dev/ttyHSUSB2.
you can use port_bridge to bridge this port to a spare smd port. see solution 00012899 about smd channel

How to add GPIO bit-bang i2c device to Linux kernel?

1. Check Kernel configuration
#define CONFIG_I2C_GPIO y
#define CONFIG_I2C_MSM y


2. Configure GPIOs at Modem side for general purpose, in/out...
You should edit TLMMBsp.c at modem side.


*3. ~ 7. You should add/modify "kernel/arch/arm/mach-msm/board-xxxxx.c"

3. Make i2c_gpio_platform_data
static struct i2c_gpio_platform_data ALRAN_i2c_gpio_data = {
.sda_pin = 91, // GPIO pin number for SDA
.scl_pin = 90, // GPIO pin number for SCL
};


4. Make platform_device
static struct platform_device ALRAN_i2c_gpio_device = {
.name = "i2c-gpio",
.id = 3, // do not be same with the another i2c_gpio_device
.dev = {
.platform_data = &ALRAN_i2c_gpio_data, // You have made it at step 3.
},
};


5. Add devices array for initdata
static struct platform_device *devices[] __initdata = {
<snip>
&ALRAN_i2c_gpio_device,
<snip>



6. Add i2c client information
static struct i2c_board_info ALRAN_i2c_devices[] = {
{
I2C_BOARD_INFO("ALRAN",0x4A>>1), // 0x4A should be changed with your device address
},
};


7. Register i2c client to board_init function
static void __init msm7x2x_init(void)
{
<snip>
i2c_register_board_info(3, ALRAN_i2c_devices, ARRAY_SIZE(ALRAN_i2c_devices));
<snip>
}
It's just for i2c client board.

How to add new clock param for SPI bus in linux build on Qualcomm chipset?

SPI clock parameters are defined in arch/arm/mach-msm/clock-xxxx.c file.


The table for the parameters is like below.


static struct clk_freq_tbl clk_tbl_spi[] = {
F_MND8(10000000, 19, 12, SRC_PLL3, 4, 7, 129),
F_MND8(26000000, 19, 12, SRC_PLL3, 4, 34, 241),
F_END,
};


Clock frequency for SPI bus is determined by M:N:D counter and the information about this is described in clock chapter of software interface manual. The concerned registers are SPI_MD_REG and SPI_NS_REG.


The example vale for 1 Mhz SPI clock is below.


F_MND8(1000000, 19, 12, SRC_PLL3, 4, 1, 185),

How to analyze the status of I2C Bus for linux build.

I2C SCL state
RESET� Bus idle; the start condition has not yet been detected.
NOT MASTER � This occurs when the I2C controller detects that another master is trying to control the bus.
This is usually the Error state, because the MSM? has only one master. It is manifested as an arbitration lost error.
HIGH � High phase of scl_out
STOP condition � Master releases control of bus and returns to the Reset state
Loss of arbitration � Go to the NOT MASTER state and wait for the other master to release the bus
Unexpected START condition � Error status
LOW � Low phase of scl_out
If data control block is requesting this, it is entering forced Low state and waiting for data control block to return to normal operation


I2C SDA state
RESET � Reset and Wait state
Either STOP condition or bus is free to commence transmission
TX ADDR � 7-bit address has been transmitted to client
When address is issued, clock is pulled to low until it receives ACK from the client
TX DATA � Data has been issued to the bus
Same with TX ADDR, except it is not generating the START condition
RX DATA � Data received from the bus
Software can set the LAST_BYTE bit to terminate transfer


In AMSS\products\XXXX\drivers\hw\t32\XXXX\


There's hwioreg.cmm script that one can use on T32
to monitor I2C SCL and SDA state.
User can type "I2C_STATUS" on menu to monitor the i2c registers
This can be done on the fly to debug i2c bus.

How to capture LeCroy CATC USB log?

USB CATC log is essential to analyze bus activity.



Here is how you can capture USB packets by LeCroy USB tracer.

(I assume you have LeCroy Product: Lecroy USB Tracer,http://www.lecroy.com/tm/products/ProtocolAnalyzers/usbtt.asp?menuid=67)



Please download LeCroy installation program:http://www.lecroy.com/tm/Library/Software/PSG/usbtracertrainer.asp?menuid=8

To get a LeCroy CATC log, please connect the device like this:

Customer Device (mini B) ----->|

Host PC(type B) ----------------->| -Lecroy USB Tracer -|<-------(typeB) Analysing PC



And then

Run the application, and then click 'Set up' menu, click 'Recording Options', and increase the buffer size as maximum.

Click the 'REC' icon to record, and then 'STOP' to finish recording in the menu bar.

Please save this *.usb file to location that you can zip it and then send to Qualcomm Apps Engineer over SR system.

How to capture modem PPP log use wireshark in Qualcoomm MDM8200?

Question:I'm running Wireshark on Windows; why doesn't my usb modem show up in the list of interfaces in the "Interface:" field in the dialog box popped up by "Capture->Start"?

Answer: The Winpcap version in your computer is not correct, you should be able to capture on the "GenericDialupAdapter" with WinPcap 3.1. (3.1 beta releases called it the "NdisWanAdapter"; if you're using a 3.1 beta release, you should un-install it and install the final 3.1 release.) See the Wireshark Wiki item on PPP capturing for details.

Direct control of sensors through apps processor on Qualcomm msm8x60

Question: How do we control sensors directly (bypassing DSPS) through the apps processor on 8x60 ?


Answer: There are two steps to be done for this:
1) Disabling of DSPS: This is done through disabling the parameter "CONFIG_MSM_DSPS" either in the file msm8660-perf_defconfig or the file msm8660_defconfig file. The file is selected depending upon the "KERNEL_DEFCONFIG" configuration specified in the makefile "AndroidBoard.mk" located at /device/qcom/msm8660_surf.
After changing the file above, a clean build must be done.

2) Voting for turning on the voltage regulators S3 and L5: The sensor drivers will need to vote to turn these regulators on. The voting can be handled in /kernel/arch/arm/mach-msm/board-msm8x60.c. For eg: if a BMA150 Linux kernel is being ported, the board file board-msm8x60.c should be modified according to the following patch:


https://www.codeaurora.org/patches/quic/la/PATCH_M8660AAABQNLYA1080_5904_turning_s3_l5_ON_for_sensor_control_20110401.tar.gz


The patch above should be referred to for any modifications.


static struct bma150_platform_data bma150_data = {
.power_on = sensors_ldo_enable,
.power_off = sensors_ldo_disable,
};


static struct i2c_board_info msm_i2c_bma150_info[] = {
{
I2C_BOARD_INFO("bma150", 0x38),
.flags = I2C_CLIENT_WAKE,
.irq = MSM_GPIO_TO_INT(BMA150_GPIO_INT),
.platform_data = &bma150_data,
}
};



Notes: The solution is based on 8x60 FFA sensor design � BMA150 controlled by GSBI12. For different sensor design, a different sensor driver and platform data structure should be created. Similarly, a different i2c_board_info structure should be created.

Does MTP supported in Android builds?

Is there support for MTP function driver in Android builds?





There is support for MTP in ICS builds by default in all the android software releases.



MTP is protocol similar to mass-storage. On ICS, MTP is the default function to access phone's storage media. It was not available on GB and but was supported in Honeycomb.



OEMS can test this feature function driver, user can enable MTP/PTP using UI Notification menu.



One thing to note here is that once user selects MTP/PTP, it is then marked as default configuration. Afterward device always enumerates with MTP even across reboots. To return to non-MTP composition user need to reprogram userdata.img or below command from shell followed by reboot:



setprop persist.sys.usb.config ""

sync







There is no support for MTP function driver from the Qualcomm in android builds before ICS and Honeycomb.



There are solutions in the market to suite such requirement. OEMs can contact third party vendors( Jungo/Packet Video) for MTP feature support in Android builds.



http://www.opencore.net/files/Android_WM_Package.pdf



http://www.jungo.com/st/embedded_usb_mtp_device.html

Enabling High Speed Electrical Test Tool (HSET) support in Linux/Andorid builds?

Enabling the High Speed Electrical Test Tool (HSET) support in Linux?
A USB high speed host must pass electrical compliance tests defined by the USB-IF in order to use the High-speed Logo. These compliance tests require the host controller to support various test modes defined by the USB 2.0 specification.



USB-IF defines a windows based High Speed Electrical Test Tool (HSET) to activate various test modes. But for small devices with embedded USB host controller it may not be possible to use the tool because of the unavailability of windows platform. Therefore, USB-IF defines a standard method to initiate test modes on embedded hosts by using a test fixture. During enumeration by the USB host, this test fixture provides a VID/PID pair which is used by the host to initiate a particular test mode as each VID/PID pair corresponds to a unique test mode.



Following are the test modes PIDs supported by LE or Android builds:

PID Test Mode

0x0101 TEST_SE0_NAK

0x0102 TEST_J

0x0103 TEST_K

0x0104 TEST_PACKET

0x0106 HS_HOST_PORT_SUSPEND_RESUME

0x0107 SINGLE_STEP_GET_DEV_DESC

0x0108 SINGLE_STEP_SET_FEATURE



Detailed instructions to perform the "Embedded High-Speed host Electrical Tests" or EHSET host compliance tests can be found in the below doc.

http://www.usb.org/developers/onthego/EHSET_v1.01.pdf



OEMs need to check the below kernel option:

CONFIG_USB_EHCI_EHSET option needs to be enable in the kernel's default configuration for EHSET host compliance test support in the build.




Also refer to the solution# 00012725(What are kernel flags need to be defined to enable HS-USB Host configuration?) to check whether host mode is enabled or not.

Fast Dead Battery Charging via USB HID Enumeration in qualcom msm7x27

This feature is used to reduce the amount of time spent on charging while usb device getting enumerated.In the mechanism,the USB device draws 100mA from Host in its enumeration process..On the completion of enumeration,i.e.after enter into the configured state, it is allowed to draw up 500mA from its Host. This 500mA current can allow the battery to be charged faster and hence it is called as "Fast Dead Battery Charging".If the enumeration of the device gets fails,i.e.not entered into the configured state,the USB device can allow the battery to draw 100mA only.

Flags to be set to enable this Fast Dead Battery Charging:

a)For all HS-USB targets except Karura(MSM7x27):
1.define FEATURE_OSBL_USB_BATT_CHG & define FEATURE_HS_USB_FAST_CHARGE_VIA_HID in build\ms\custxxxxx.h file
2.hsu_fast_charge makeonly in *.builds file

b)Karura(MSM7x27):
1.define FEATURE_OSBL_USB_BATT_CHG & define FEATURE_HS_USB_FAST_CHARGE_VIA_HID in build\ms\custxxxxx.h file
2.hsu_chg_boot makeonly in *.builds file

This feature is applicable for only HS-USB targets.

How can I switch HS USB composition without resetting the device in Qualcomm MDM8200?

Q) How can I switch HS USB composition without resetting the device in Jungo code?
or

Q) Looking for information about the hsu_set_compositon() API?
or
Q)What are API's help in the HS USB composition switching?

A) Switching HS USB composition without resetting the device is called the hs-usb dynamic switching of composition. For static switching OEM's need to change the NV#4526 value and reset the device. Please check the composition_details[] to know the all the compositions supported.

Dynamic Composition Switching:
There are two set of APIs supporting the dynamic switching
1) hsu_set_compositon() from the Hsu_conf_sel_rdm.c file(NEW API).
2) hsu_conf_sel_ui_switch_comp() from the file Hsu_con_sel_ui.c(OLD API).

General steps followed to switch the composition:
1) Closing ports: All the ports opened in the current composition is closed with rdm_assing_port()/rdm_close_device().
2) Stack Switching: Switch the HS USB stack to support the new set of Functional drivers in the target composition. hsu_conf_sel_switch_dev_stack() does the switching of the HS USB stack.
3) Opening ports: Open each port in the target composition with rdm_assign_port().


1) Note1: hsu_set_composition() function and all its related functions are listed in Hsu_conf_sel_rdm.c file.
2) Note2: hsu_conf_sel_ui_switch_comp() and all it related functions are listed in Hsu_conf_sel_ui.c file.
3) Note3: if you find any port is not working after using the hsu_conf_sel_ui_switch_comp(), please open a CASE.







Supplement to the solution on February 19, 2010:


We have 2 options to perform dynamic switch and we don't recommend using hsu_conf_sel_ui_switch_comp.

Option 1 :
Call hsu_conf_sel_switch_dev_stack and rdm_assign_port directly from application. For this application, it should be assured that the hsu_conf_sel_switch_dev_stack and rdm_assign_port are called from the application context.

Example sequence as follows.
a. Application task call hsu_conf_sel_switch_dev_stack with call back, switch_dev_cb.
b. Application task wait until switch_dev_cb is called. (eg: rex_wait and rex_set_sigs can be used.).
c. switch_dev_cb is called by HS_USB0 task and notify application task of the completion of comp switch.




* Application task call hsu_api_spoof_reconnect(). Only valid for QSC11x0 which has enabled the feature FEATURE_HS_USB_PMIC_PHY.



d. Application task calls rdm_assign_port with rdm_cb.
e. Application task wait unitl rdm_cb is called.
f. rdm_cb is called by some task( The caller on rdm_cb varies depending on the service) and notify application task of the completion rdm_assign_port.
h. Application repeats from step d to step f.

Option 2 :
Use new API hsu_set_composton which has been submitted recently.

void hsu_set_compositon
(
hsu_conf_sel_composition_id_enum composition_id,
hsu_set_comp_cb_type complete_cb,
hsu_rdm_dev_svc_pare_type *old_rdm_map,
juint8_t old_rdm_map_size,
hsu_rdm_dev_svc_pare_type *new_rdm_map,
juint8_t new_rdm_map_size
);

Example usage is :

Hsu_rdm_dev_srv_pare_type new_rdm_map[2] = {
{RDM_USB_DIAG_DEV,RDM_DIAG_SRVC},
{RDM_USB_MDM_DEV,RDM_DATA_SRVC}
}

Void complete_cb(boolean status)
{
hsu_api_spoof_reconnect();


* Only valid for QSC11x0 which has enabled the feature FEATURE_HS_USB_PMIC_PHY.
}

Application context :

hsu_set_compositon(
HSU_CONF_SEL_DIAG_MDM_COMP,
complete_cb,
NULL,
NULL,
new_rdm_map,
2
);

We redommand option 1 for the targets which does not have the API.

How can I access Data Service over 2 different USB serial port at same time?

Q) How can I access Data Service over 2 different USB serial port at same time?
or
Q) Changes required to enable the Second AT command port?
Details: Qualcomm supports one CDC-ACM(in HS-USB or FS-USB) port for data service, if DUN is established this single port is dedicated for data service. If OEM's want to send control AT commands to ATCOP, it is not possible once DATA call is established.

OEM's required SECOND at command port to send the AT commands. To have second at command port OEM's can create new USB cdc-obex port. Features FEATURE_DATA_SERIALIZER and FEATURE_DATA_MULTI_PORTS helps to create new AT command port.

HS-USB:
Q) Is it possible to create NEW CDC-ACM instance in the Jungo HS USB code?
A)NO. There is no support for CDC- ACM to create new instance. OEM's have to use the CDC-OBEX instance to create new AT command port.
All the changes required in the HS-USB driver code and DS3gsiolib to create new AT command port is listed in the doc#80-VT282.

FS-USB:
If OEM's require this Second AT command port in the FS-USB, they can use the existing NMEA port(if they are not using) or by creating new OBEX port in the usbcdc.c file. Same DS3gsiolib modification listed in doc#80-VT282, works for FS USB supported chip set. if they want to use the NMEA port all they need is changing of the port mappings.

NOTE: FEATURE_DATA_SERIALIZER and FEATURE_DATA_MULTI_PORTS should be defined in the build.

For more information you can reference article #00002889; What is the Serializer and Multi-Port Support?

GSBI Protocol Code/PIN mappings in qualcomm MSM8660, MSM8660A, MSM8960

When GSBI protocol code is configured to below functions, related PIN are configured as below.


protocol code 1 I2C + SIM/R-UIM
GSBI_PO(0) i2c_clk
GSBI_PO(1) i2c_dat
GSBI_PO(2) uim_clk
GSBI_PO(3) uim_dat


Protocol code 2 I2C
GSBI_PO(0) i2c_clk
GSBI_PO(1) i2c_dat
GSBI_PO(2) not used
GSBI_PO(3) not used


Protocol code 3 SPI
GSBI_PO(0) spi_clk
GSBI_PO(1) spi_cs_n
GSBI_PO(2) spi_data_miso
GSBI_PO(3) spi_data_mosi


Protocol code 4 UART or IRDA
GSBI_PO(0) uart_rfr_n
GSBI_PO(1) uart_cts_n
GSBI_PO(2) uart_rx_dat
GSBI_PO(3) uart_tx_dat


Protocol code 5 SIM/R-UIM
GSBI_PO(0) not used
GSBI_PO(1) not used
GSBI_PO(2) uim_clk
GSBI_PO(3) uim_dat


protocol code 6 I2C + 2-wire UART
GSBI_PO(0) i2c_clk
GSBI_PO(1) i2c_dat
GSBI_PO(2) uart_rx_dat
GSBI_PO(3) uart_tx_dat

GSBI Configuration for I2C on quaclomm Android msm8660

Question: What steps should be followed for the configuration of a particular GSBI for I2C on 8660 ?


Answer: Steps to be followed for the GSBI configuration for I2C:


Suppose the GSBIx is to be configured:


1) In file devices-msm8x60.c, add:
static struct resource gsbix_qup_i2c_resources[] = {
{
.name = "qup_phys_addr",
.start = MSM_GSBIx_QUP_PHYS,
.end = MSM_GSBIx_QUP_PHYS + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "gsbi_qup_i2c_addr",
.start = MSM_GSBIx_PHYS,
.end = MSM_GSBIx_PHYS + 4 - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "qup_err_intr",
.start = GSBIx_QUP_IRQ,
.end = GSBIx_QUP_IRQ,
.flags = IORESOURCE_IRQ,
},
};


/* Use GSBIx QUP for /dev/i2c-5 (i.e. if i2c-5 has not been used before else choose the next number) */
struct platform_device msm_gsbix_qup_i2c_device = {
.name = "qup_i2c",
/* this BUS_ID has been mapped to 5 inside the file devices-msm8x60.h. this part has been explained below */
.id = MSM_GSBIx_QUP_I2C_BUS_ID,
.num_resources = ARRAY_SIZE(gsbix_qup_i2c_resources),
.resource = gsbix_qup_i2c_resources,
};

In the same file, inside the structure, struct clk msm_clocks_8x60[] = {
/* change the following : */
CLK_8X60("gsbi_qup_clk", GSBIx_QUP_CLK, NULL , 0),
/* to: */
CLK_8X60("gsbi_qup_clk", GSBIx_QUP_CLK, &msm_gsbix_qup_i2c_device.dev, 0),

/* and change the following: */
CLK_8X60("gsbi_pclk", GSBIx_P_CLK, NULL , 0),
/* to: */
CLK_8X60("gsbi_pclk", GSBIx_P_CLK, &msm_gsbix_qup_i2c_device.dev, 0),

2) In file board-msm8x60.c:

A) Add
static struct msm_i2c_platform_data msm_gsbix_qup_i2c_pdata = {
.clk_freq = 100000,
.src_clk_rate = 24000000,
.clk = "gsbi_qup_clk",
.pclk = "gsbi_pclk",
.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
};

B) Modify
static struct platform_device *surf_devices[] __initdata = {
/* add the following: */
&msm_gsbix_qup_i2c_device,

C) Add
/* in section #ifdef CONFIG_I2C_QUP of msm8x60_init_buses() , add */
msm_gsbix_qup_i2c_device.dev.platform_data = &msm_gsbix_qup_i2c_pdata;

3) In file devices.h, add:
extern struct platform_device msm_gsbix_qup_i2c_device;

4) in file devices-msm8x60.h, add:
/* if 5 has already been used, then the next consecutive number */
#define MSM_GSBIx_QUP_I2C_BUS_ID 5

Diag over UART on qualcomm MDM8200, MDM8220, MDM9200, MDM9600

In modem_proc\build\cust\custsio_XXXX.h, look for
"#define RDM_USB_SER1_INIT_SRVC RDM_DIAG_SRVC"
and comment out this line.
Then look for
"// #define RDM_UART1_INIT_SRVC RDM_DIAG_SRVC"
and uncomment this line; if you don't find it, please add it.
This is to disable RDM_USB_SER1_INIT_SRVC and enable RDM_UART1_INIT_SRVC for DIAG service in RDM.
Obviously, you need to make sure UART being used is available, say for UART1 - FEATURE_USE_UART1DM should be defined.
Recompile the build with these changes. Please do erasenand.cmm to erase flash and then load the re-compiled build.


Alternative way is to route DIAG over UART is to modify rdm_config.csv from EFS directly as below:
1. Open EFS explorer
2. Locate rdm_config.csv file at the root level, and copy rdm_config.csv file from EFS explorer to local host machine.
3. Edit rdm_config.csv file using text editor (make sure that the comma separation between each column is maintained). Current portmapping and default portmapping for a device can be changed by editing "current service" and "default service" column for that device respectively.
- First two columns, Device ID and Device Name should not be modified as its not configurable.
- Service and Device names are exactly same as the symbol names (enum type) defined in rdevmap.h.
- If the string doesn't match with any of the service defined in rdm_service_enum_type (rdevmap.h), then RDM_NULL_SRVC would be used.
Please make sure that devices and services are compatible with each other before making change. If user tries to map a service to a device which is not compatible with that service, then RDM will remove the port mapping from rdm_config.csv file.
NOTE: EFS explorer requires the DIAG connection, so please be careful while re-mapping RDM_DIAG_SRVC to other devices. If the RDM_DIAG_SRVC is not mapped to one of the compatible device, then DIAG will not be functional, and user will loose the access to EFS file system and there will be no way to access rdm_config.csv file.
4. Delete the rdm_config.csv file from EFS explorer, and copy the edited rdm_config.csv file from local host to EFS explorer. (Note: if you try to replace the rdm_config.csv file without deleting it, then make sure that file is successfully copied by refreshing EFS explorer.
5. Restart the phone.


Make sure that the entry 1 and 6 look as follows:
1, RDM_UART1_DEV, RDM_DIAG_SRVC , RDM_DIAG_SRVC, YES,
6, RDM_USB_SER1_DEV, , , YES,
Note: Modify rdm_config.csv using VIM or notepad++ (don't use wordpad or excel) to make sure format is retained.

Connecting QPST over uart1dm in qualcomm android code

IN order to connect QPST over uart1dm please make the following changes


make the following changes.

1) in \build\cust\custsio.h
comment out
//#define RDM_USB_SER1_INIT_SRVC RDM_DIAG_SRVC
and add
#define RDM_UART1_INIT_SRVC RDM_DIAG_SRVC

2) in drivers\sio\rdevmap.c
add UART1DM_BM to diag compatible ports.
rdm_srv_dev_compat_tab[RDM_DIAG_SRVC] = (RDM_NULL_DEV_BM
#ifndef FEATURE_BT_SOC_UART_TL
| RDM_UART1_BM

Comparison between Self-powered hub and Bus-powered hub

here are many request from customer to explain the behavior of two kinds of hubs: Self-powered hub and Bus-powered hub.

Some issues are due to this behavior.



For example,

When USB Cabel is connected or disconnected to the certain hub, Other USB device ( Keyboard, Mouse,etc) does not work normally.

The reason for this issue is following:
When the device turns on charging, it request 500mA from the USB, so other devices which attached to 'bus-powered' hub (which does not connect to power source) are not able to work well.



Here is the comparison between Self-powered hub and Bus-powered hub



A bus-powered hub is a hub that draws all its power from the host computer's USB interface. It does not need a separate power connection. However, many devices require more power than this method can provide, and will not work in this type of hub.

USB current (related to power) is allocated in units of 100 mA up to a maximum total of 500 mA per port. Therefore a compliant bus powered hub can have no more than four downstream ports and cannot offer more than four 100 mA units of current in total to downstream devices (since one unit is needed for the hub itself). If more units of current are required by a device than can be supplied by the port it is plugged into, the operating system usually reports this to the user.

In contrast a self-powered hub is one that takes its power from an external power supply unit and can therefore provide full power (up to 500mA) to every port. Many hubs can operate as either bus powered or self powered hubs.

However, there are many non-compliant hubs on the market which announce themselves to the host as self-powered despite really being bus-powered. Equally there are plenty of non-compliant devices that use more than 100 mA without announcing this fact (or indeed sometimes without identifying themselves as USB devices at all). These hubs and devices do allow more flexibility in the use of power (in particular many devices use far less than 100 mA and many USB ports can supply more than 500 mA before going into overload shut-off) but they are likely to make power problems harder to diagnose.
"
-Quoted from open-site wiki, http://en.wikipedia.org/wiki/USB_hub.
For more details, you can refer to USB standard 2.0.
Please remind this:
"
However, there are many non-compliant hubs on the market which announce themselves to the host as self-powered despite really being bus-powered.
"

In my office, I also confirmed my hub(D-Link) after taking off power cable, still recognized as 'self-powered' to host PC.

To check your hub is either self-powered, or bus-powered, you can check, Device Manager -> View ->Device by connection , and then right click on 'USB Root Hub' and then click 'Properties', click the tab, 'Power'. you can see how host recognize the hub.

Can we disable session/vbus comparators in integrated usb phy in Qualcomm MDM8200?

Yes we can disable session/vbus comparators inside usb phy.

Add below code at the end of hsu_api_init_phy() corresponding to separate platform will do,



uint8 read_value = 0;
/*Disable session end/session valid/VBUS valid rise interrupt*/
HAL_hsusb_ReadUlpiPhy(0, 0, 0xd, &read_value);
read_value= read_value&0xf1;
HAL_hsusb_WriteUlpiPhy(0, 0, 0xd, read_value);
/*Disable session end/session valid/VBUS valid fall interrupt*/
HAL_hsusb_ReadUlpiPhy(0, 0, 0x10, &read_value);
read_value= read_value&0xf1;
HAL_hsusb_WriteUlpiPhy(0, 0, 0x10, read_value);





Disabling these interrupts may eliminate curious timeouts for IN/OUT transfer when modem work in device mode.

As these interrupts is useful in host mode, these code should not be used to products having host function.

Can we customize the interface number in the Android composite device?

Q) Can OEMs change the interface order in the Android composite device?

Yes, OEMs can modify usb_func_composition[] array instance in kernel/arch/arm/mach-msm/board-XXXXX.c file.

.functions variable in array instance contains interface order.

OEMs can change the interface order in the Android composite devices with this variable. If OEMs are using the gadget frame work for usb driver, check the function android_bind_config() to know how the interfaces are added to android composite device.



When OEM changes the interface order, they also need to change .inf files of Host driver so that there will not be any detection problem.

It is recommended that DIAG interface, should be always first interface in a compositions. So that when device switches to DLOAD mode there will not be any COM port change.



Q) Can OEMs change the interfaces number in non sequential order with android composite device?

Ans) usb_interface_id() function in the Composite.c file need be changed so that for each interface gets unique interface number according to OEMs requirements.

Can I implement usb NIC or use QMI/NDIS interface for linux/android build

Question: Can I use QMI/NDIS interface for linux/android build? Can I make PC to see a network interface card(NIC) when phone connect PC by usb?
Answer:
The current android/LE release kernel has a standard ECM function driver, this can make the phone expose a standard usb ecm interface to PC.
There are existing standard usb ECM host driver for standard ecm on linux/MAC, but no on Windows.
The Windows has its own R-NDIS driver with its special usb ecm standard, it is used on Windows mobile phones.
The QMI/NDIS interface is Qualcomm's usb NIC interface,it is supported on most of Qualcomm's 6K platform and it must work with Qualcomm's usb host driver.
Qualcomm also implement it on android release with a usb function driver in linux kernel. It just routes the usb control and data flow from linux to amss side.
The driver is located at drivers/usb/function/rmnet.c
So you have different choice to implement usb NIC on different PC OS with different host driver:
Standard ECM -- You need a usb host driver for Windows either develop it yourself or find a vendor.
R-NDIS -- You need implement the usb function driver in linux kernel, and need linux/MAC host driver if you want to support these two OS.
QMI/NDIS -- You can use the same host driver as Qualcomm's 6K product, and also need develop linux/MAC host driver.

Can Qualcomm MSM8960 apps processor control GSBI11 and GSBI12?

Yes, 8960 apps processor can control GSBI11 and GSBI12.
The 12 GSBIs are shared resource and can be directly accessed by all processors.

GSBI11 is SPS GSBI1 and the controller address base is 0x12440000.
GSBI12 is SPS GSBI2 and the controller address base is 0x12480000.

Calculation of the UART2DM Baud Rates in qualcomm AMSS7x30/AMSS7x27 Software

The equation to calculate the UARTDM Baud Rate is as follows:



Baud rate = 1/16 * Input clock rate * 1/CSR Value,

Input clock rate= Source clock rate * (M/N) * (1/P) where P = 1, 2 or 4.

P is the value in UART2DM_NS_REG[4:3]

M, N can be derived from the registers UART2DM_MD_REG and UART2DM_NS_REG respectively.




For a CSR= 0xFF, CSR Value = 1; for CSR = 0xEE, CSR Value = 2.

For a CSR= 0xDD, CSR Value = 3; for CSR = 0xCC, CSR Value = 4.

For a CSR= 0xBB, CSR Value = 6; for CSR = 0xAA, CSR Value = 8.

For a CSR= 0x99, CSR Value = 12; for CSR = 0x88, CSR Value = 16.

For a CSR= 0x77, CSR Value = 24; for CSR = 0x66, CSR Value = 32.

For a CSR= 0x55, CSR Value = 48; for CSR = 0x44, CSR Value = 96.

For a CSR= 0x33, CSR Value = 192; for CSR = 0x22, CSR Value = 384.

For a CSR= 0x11, CSR Value = 768; for CSR = 0x00, CSR Value = 1536.



For Eg.: for a baud rate of 4Mbps, Input Clock Rate= 16 * 4 MHz * 1 (CSR = 0xFF) = 64MHz. We just need to calculate the input clock rate without bothering about the M, N, P values. These values have already been configured to achieve a given input clock rate.



The file clkrgm_bsp_xxxx.c (eg. clkrgm_bsp_7627.c) has different values of input clock rates which can be selected to achieve a given baud rate. If a particular input clock rate is not specified in this file, then please open a case with the Modem Clock team for that input clock rate to be added to the list of clock rates supported.

What is the API or callback function when the Wall charger or USB host is detected in Qualcomm modem?

When the wall-charger is detected, D+ and D- are shorted, and hsu_chg_wallchg_detect() is called.

and the boolean varaible, 'is_wall_charger' should be true.



In the case that USB host is connected, initially D+ will goes high, and D- low, and otg_notify_device_mode_cb() is called. hsu_conf_sel_stack_utils_handle_chg_connect() is followed.

Adding Dal i2c to osbl in Qualcomm AMSS 7630 Software

in order to add the dal i2c driver to the osbl layer the following two steps must be performed.


1) copy i2cprops.xml from core\dal\config\<amss/apps> to core\dal\config\boot_osbl. This will ensure that the dal i2c drivers properties are available in osbl stage.


2) modify the sconscript at every subdirectory within core\buses\i2c\<dal,dalpd,hal> so that the i2c object files are added to the osbl image.


here is the snippet showing that


env.AddLibsToImage(
['SINGLE_IMAGE', 'CBSP_SINGLE_IMAGE', 'MODEM_IMAGE', 'CBSP_MODEM_IMAGE',
'APPS_IMAGE', 'CBSP_APPS_IMAGE', 'OSBL_BOOT_IMAGE'],
[dal_i2c_lib, dal_i2c_sh_lib])

about change the sequence of interfaces in composite device in high speed usb stack

Question: Can we change the sequences of interfaces in composite device? Like we want the modem as the first interface?
----------
Answer: Yes, you can modify code in build_fd_struct()
Detail: By default on the hsu stack, in the composite device, the diag will be the first interface in the composite device, and NMEA(for GPS) will be the second one, then mass storage, modem, NDIS.
Why diag is the first? Because when switch to download mode, only diag port exists, to order to keep the same COM port in Windows, so in amss, diag is the first interface.If you want modem as the first interface, you shall consider this download issue.
If you use your own download application, it shall have the feature to detect the COM port if it changes. You can change the initialization sequence for different fd in build_fd_struct(). The sequence is related with fd in fds_to_init[], so you can change the sequence in build_fd_struct().

Can UART2DM used for linux kernel debugging purpose on Qualcomm MSM7x27A?

Can UART2DM used for debugging purpose on MSM7x27A?

MSM7x27A have the two UARTDM cores, UART1DM and UART2DM and three Legacy UART cores, UART1, UART2, UART3 exits.



If OEMS board is using the UART1DM for BT, UART1 core can be used console for debugging purpose. Both UART1DM and UART cores are using different GPIOs and UART1DM used for BT chipset mostly.



There is also other option, OEMS can use UART2DM for debugging purpose.





Configuration changes:-

# Do make kernelconfig, Go to Device Drivers --> Character Devices--> Serial Drivers--> "MSM on-chip serial support". Deselect the same.

# In same step above menu, select "MSM UART High Speed: Legacy mode Serial Driver" and "MSM High Speed serial legacy mode console support".



# Also disable SDC4 and SDC3 8-bit support from Device Drivers-->MMC/SD/SDIO Card Support and deselect Qualcomm SDC3 Support from the same.

# Go to System type menu and select Use Shared GPIOs into UART Mode which enables CONFIG_MSM_SHARED_GPIO_FOR_UART2DM.



#Add ttyHSL0 into device/qcom/msm7627a/BoardConfig.mk file or copy below line in the same.

BOARD_KERNEL_CMDLINE := console=ttyHSL0,115200n8 androidboot.hardware=qcom





# Check the .config file Check if CONFIG_SERIAL_MSM=y and CONFIG_SERIAL_MSM_CONSOLE=y are enabled or not.







Using EBI2 Gpios for UART2DM-



The above configuration changes will enable UART2DM with (GPIO_108, GPIO_19, GPIO_20, GPIO_21).



For customer designs that use 8-bit eMMC boot instead (i.e. GPIOs 19-21 and 108 will be used for the 8-bit eMMC boot), then EBI2 interface will be un-used.

Hence customers can make use of UART2_DM port muxed behind EBI2 interface in the case of eMMC boot.



EBI2_A_D_6, EBI2_A_D_7, EBI2_A_D_8, EBI2_A_D_9 can be configured as UART2DM gpio's. Please refer to the Software interface manual for this.

Setting bit 4 of this TMUX_EBI2 register to 1, will allow the usage of UART2_DM port behind EBI2 interface, when the customer design intends to use eMMC boot.

6/14/2012

Sleep Mechanism in Qualcom msm8x55 chipset ---- Debugging Tips 2

The following APIs can be used to write into the smem log.


void smem_log_event ( smem_log_area area, uint32 id, uint32 reserved,
uint32 data1, uint32 data2, uint32 data3 );
void smem_log_event6 ( smem_log_area area, uint32 id, uint32 reserved,
uint32 data1, uint32 data2, uint32 data3,
uint32 data4, uint32 data5, uint32 data6);



Note that the sleep_log_event also writes to the smem log (both circular and power circular
buffers) when FEATURE_SMEM_LOG is defined. If smem log is not available, it writes to
sleep_trace.


void sleep_log_event
(
/* Event to be logged */
uint32 event,

)



Arbitrary data to log */ uint32 a32, uint32 b32, uint32 c32



Here are some commonly used MACROs defined based on smem_log_event APIs.


#define SMEM_LOG_EVENT(identifier,data1,data2,data3) \
smem_log_event(SMEM_LOG_AREA_CIRCULAR_MPROC, \
identifier, 0, data1, data2, data3)
#define SMEM_LOG_EVENT_EX(area, id, reserved, data1, data2, data3) \
smem_log_event(area, id, reserved, data1, data2, data3)
#define DEM_LOG_EVENT(event, data1, data2, data3) \
SMEM_LOG_EVENT(event, data1, data2, data3)
#define ONCRPC_LOG_EVENT(event, data1, data2, data3) \
SMEM_LOG_EVENT( event, data1, data2, data3 )
#define CLKREGIM_SMEM_LOG_EVENT(a,b,c,d) \
SMEM_LOG_EVENT_EX(SMEM_LOG_AREA_CIRCULAR_POWER, \
SMEM_LOG_CLKREGIM_##a, 0, b, c, d)


Collecting SMEM log

To collect the shared memory log, you need first run the smemlog.cmm script in
\AMSS\products\7x30\tools\debug from T32.


do smemlog.cmm C:\temp



You can replace C:\temp with a directory where you want the output files to be saved. This script
prints out several *.lst files, which contain raw smemlog data dumped from device memory.

To parse these output files into readable version of log information, you can run the smem_log.pl
script from a command window, e.g., you can parse the log and save it as a .txt file.


perl smem_log.pl [-t] > smemlog.txt



The optional -t parameter will force timestamps to show up in native slow clock ticks. This can be
useful when you need to compare smemlog to other logs such as tramp_log, mao_trace, etc.
Without this option, the timestamps are converted into seconds.

The output of smem_log.pl includes several entries for each RPC call. If you are not interested in
the RPC messages, you can run smem_log_filter.pl to filter RPC-related messages out of the log,
e.g.:


perl smem_log.pl | perl smem_log_filter.pl > smemlog_filter.txt


perl smem_log_filter.pl smemlog.txt > smemlog_filter.txt



Reading SMEM log

Modem deep sleep

The shared memory log contains very useful information on the device's sleep operation. A
parsed smem log entry often takes the following format.


Processor: Timestamp Module: Event data1 data2 data3



For instance, the following logs show that the Sleep module of the modem recorded this entry at
101.890594 secs when the modem decided to enter deep sleep. The first data item shows that the
prescribed sleep time is 0x1004 slow clock ticks (~128 ms).


MODM: 101.890594 SLEEP: ENTER TCXO 1004 0 0



If we look at the code, we can see this log entry is recorded by the following line of
sleepmod_tcxo_shutdown.


sleep_log_event( MOD_ENTER_TCXO, uNextWakeupSclk, 0, 0 );



The above log should always be accompanied by a TCXO END smem log entry such as follows.


MODM: 102.012438 SLEEP: TCXO END 0 1 0



Similarly, this entry is logged by the following line inside the same API.


sleep_log_event( MOD_TCXO_END, 0, maoint_get_pending_ints(), 0 );



Therefore, we know the modem came out of deep sleep at 102.012438 sec, and the total sleep
time is about 122 ms, which is close to the prescribed sleep time. This is also explained by the
fact that the modem is awakened from deep sleep by MAO interrupt at bit 0, which is the timer
interrupt in the MPM block.


102.012438 - 101.890594 = 0.121844




Fail to enter deep sleep

Besides deep sleep events, the modem also logs the reason why it did not enter deep sleep when
the sleep task gets a chance to run, e.g., the following log entry shows that at 102.017813 sec, the
modem was prevented from entering deep sleep because there was insufficient time.


MODM: 102.017813 SLEEP: INSUF TIME 0000353c 0000001d ffffffff



This is logged by the following code.


sleep_log_event( INSUF_TIME, uNextSleepCtlSclk, uNextTimerSclk,
uNextAltSclk );



Therefore, we know the modem could not sleep because there is a software timer expiration in
0x1d ticks, but smem log does not log which software timer it was. Examining timer_trace when
available should tell what timer expired after this event.

Sometimes the modem cannot enter deep sleep because certain modules are voting against it, e.g.,
the following logs show that at different times CLKREGIM, WL1, APROC, and ADC were
voting against sleep.


MODM: 101.790875 SLEEP: NO SLEEP - CLKREGIM WL1
MODM: 101.889313 SLEEP: NO SLEEP � APROC
MODM: 109.661563 SLEEP: NO SLEEP - WL1
MODM: 110.957969 SLEEP: NO SLEEP - ADC

Besides sleep votes, the shared memory log also shows when sleep resources are
acquired/released by modules. The following log sequence shows that WL1 acquired the sleep
resources and this caused the modem to not be able to enter deep sleep. Later when WL1 released
these resources, the modem did an XO shutdown.


MODM: 109.661438 SLEEP: RESOURCE ACQUIRED: resources TCXO MEMORY
VDD_MIN APPS_SLEEP APPS_PWRC by WL1
MODM: 109.661563 SLEEP: NO SLEEP - WL1
MODM: 109.676063 SLEEP: RESOURCE RELEASED: resources TCXO MEMORY
VDD_MIN APPS_SLEEP APPS_PWRC last voter WL1
MODM: 109.677156 SLEEP: ENTER TCXO 00004e7e 0 0
MODM: 110.298688 SLEEP: TCXO END 0 1 0




Apps sleep

The following shows a sequence of DEM logs when apps enters sleep.


MODM: 100.046031 DEM: SMSM ISR: entry: APPS DEM STATE cleared bits: RUN
set bits: SLEEP
MODM: 100.046094 DEM: STATE_MACHINE_ENTER 0 0
0
MODM: 100.046125 DEM: STATE CHANGE: master leaving RUN and entering
SLEEP WAIT
MODM: 100.046156 DEM: SETUP SLEEP 0 0000062d 0
MODM: 100.04675 DEM: APPS SWFI 0 0 0
MODM: 100.046781 DEM: STATE CHANGE: master leaving SLEEP WAIT and
entering SLEEP CONFIRMED
MODM: 100.046781 DEM: ASSERT OKTS 0 0 0



It starts when the modem receives an SMSM state transition from apps, which notifies the modem
that apps has switched from the Run to the Sleep state. Accordingly, the modem responded by
transitioning the DEM master state from Run to SLEEP_WAIT, and set up apps for sleep with
sleep time 0x62d (~49.4 ms). Then the modem receives the SWFI_IRQ when apps enters the
SWFI state, and updates the DEM master state from SLEEP_WAIT to SLEEP_CONFIRMED.
Afterwards, DEM master asserts OKTS on behalf of apps.

The following is the corresponding wakeup sequence for this apps sleep.


MODM: 100.095688 DEM: TIMER EXPIRED 2 0 0
MODM: 100.095688 DEM: STATE_MACHINE_ENTER 1 1
0
MODM: 100.095688 DEM: STATE CHANGE: master leaving SLEEP CONFIRMED and
entering SLEEP EXIT
MODM: 100.095688 DEM: NEGATE OKTS 1 0 0
MODM: 100.095719 DEM: SEND WAKEUP 0 0 0
MODM: 100.095875 DEM: SMSM ISR: entry: APPS DEM STATE cleared bits:
SLEEP set bits: SLEEP_EXIT
MODM: 100.096031 DEM: SMSM ISR: entry: APPS DEM STATE cleared bits:
SLEEP_EXIT set bits: RUN
MODM: 100.096125 DEM: STATE_MACHINE_ENTER 1 1
0
MODM: 100.096125 DEM: DETECT RUN 0 0 0
MODM: 100.096125 DEM: STATE CHANGE: master leaving SLEEP EXIT and
entering RUN
MODM: 100.09625 SLEEP: NO SLEEP - CLKREGIM APROC





We can see that DEM first detects that apps sleep time has expired after about 49 ms. Thus, it
transitions the DEM master state from SLEEP_CONFIRMED to SLEEP_EXIT, votes against
sleep, and sends out a wakeup interrupt. When apps comes out of sleep, it switches the SMSM
state (from SLEEP to SLEEP_EXIT, then to RUN) and notifies DEM master. Once the modem
detects that apps is now in the Run state, it transitions the DEM master state from SLEEP_EXIT
to RUN. As a result, we see that apps shows up in the list of modules that votes against sleep.

Apps power collapse goes through similar handshaking and the DEM state transitions. Once such
a sequence of entering apps power collapse is shown below.


MODM: 0xcf37bf89 DEM: SMSM ISR: entry: APPS DEM STATE cleared bits: RUN
set bits: PWRC
MODM: 0xcf37bfa9 DEM: STATE_MACHINE_ENTER 0 0
0
MODM: 0xcf37bfb2 DEM: STATE CHANGE: master leaving RUN and entering RSA
MODM: 0xcf37c02d DEM: SETUP POWER COLLAPSE 0 0
0
MODM: 0xcf37c0f9 DEM: APPS SWFI 0 0 0
MODM: 0xcf37c11c DEM: STATE_MACHINE_ENTER 1 0
0
MODM: 0xcf37c11e DEM: STATE CHANGE: master leaving RSA and entering RSA
CHECK INTS
MODM: 0xcf37c121 DEM: STATE CHANGE: master leaving RSA CHECK INTS and
entering RSA CONFIRMED
MODM: 0xcf37c123 DEM: REMOVE PROC PWR from APPS
MODM: 0xcf37c157 DEM: ASSERT OKTS 0 0 0



We can see that the apps first changes its SMSM state from RUN to PWRC, and the modem
DEM switches from RUN to RSA. After the modem prepares the apps for power collapse, apps
enters SWFI. Then the modem DEM checks interrupts, enters the RSA_CONFIRMED state,
removes power from the apps, and asserts OKTS.

The following is the corresponding waking-up sequence.


MODM: 0xcf37fe69 DEM: TIMER EXPIRED 2 0 0
MODM: 0xcf37fe6b DEM: STATE_MACHINE_ENTER 1 1
0
MODM: 0xcf37fe82 DEM: STATE CHANGE: master leaving RSA CONFIRMED and
entering RSA WAKING
MODM: 0xcf37fe85 DEM: NEGATE OKTS 2 0 0
MODM: 0xcf37fe8b DEM: RESTORE PROC PWR to APPS
MODM: 0xcf37ff39 DEM: SMSM ISR: entry: APPS DEM STATE cleared bits: PWRC
set bits: WFPI
MODM: 0xcf37ff44 DEM: STATE_MACHINE_ENTER 1 1
0
MODM: 0xcf37ff46 DEM: STATE CHANGE: master leaving RSA WAKING and
entering RSA RESTORE
MODM: 0xcf38006f DEM: TIME SYNC REQUEST from APPS




MODM: 0xcf380071 DEM: TIME SYNC START: servicing APPS
MODM: 0xcf38007b DEM: SMSM ISR: entry: APPS DEM STATE cleared bits: WFPI
TIME INIT set bits: RUN TIME REQUEST
MODM: 0xcf380083 DEM: TIME SYNC POLL from APPS
MODM: 0xcf380086 DEM: TIME SYNC SEND VALUE: sclk of -818413434 to APPS
MODM: 0xcf380088 DEM: SMSM ISR: entry: APPS DEM STATE cleared bits: TIME
REQUEST set bits: TIME POLL
MODM: 0xcf38008f DEM: TIME SYNC INIT from APPS, offset was 0
MODM: 0xcf380097 DEM: TIME SYNC DONE 0 0 0
MODM: 0xcf380099 DEM: SMSM ISR: entry: APPS DEM STATE cleared bits: TIME
POLL set bits: TIME INIT
MODM: 0xcf3800ac DEM: STATE_MACHINE_ENTER 1 1
0
MODM: 0xcf3800c8 DEM: STATE CHANGE: master leaving RSA RESTORE and
entering RUN



Besides DEM state transitions and negating OKTS, DEM also conducts a slow clock
synchronization when apps is exiting power collapse so that the slow clocks on two subsystems
remain synchronized. This is done by passing the slow clock tick on the modem to the apps
through the shared memory. The apps then calculates the delta to compensate for the difference.


Inserting SMEM log

It is often useful to insert additional smem logs in the code to debug sleep-related issues, e.g., the
following entry adds a new log event using the SMEM_LOG_EVENT macro.


SMEM_LOG_EVENT(0xa, 0, 0, 0);



Note that bits 27-16 of the event identifier is interpreted as the subsystem ID (event base), and
0x0 is DEBUG_EVENT_BASE.


/** Event base for debug log events. */
#define SMEM_LOG_DEBUG_EVENT_BASE 0x00000000



The above entry shows up in the smem log as a DEBUG log line as follows.


MODM: 108642.298250 DEBUG: 0000000a 00000000 00000000 00000000




Other logs

This section discusses a few additional useful logs for debugging sleep or power issues.


Tramp log

Interrupt logs are guarded by the FEATURE_TRAMP_LOG compiler switch. The tramp_log
provides a short history of interrupts.


typedef struct
{

tramp_log_event_type event;
tramp_irq_type irq;
uint32 timestamp;
tramp_pic_log_level_type level;
uint32 in_stack;
uint32 in_service;
} tramp_log_entry_type;
typedef struct
{
uint32 index;
tramp_log_entry_type entries[MAX_TRAMP_LOG_ENTRIES];
} tramp_log_type;
static tramp_log_type tramp_log;



To collect tramp_log, you can use the following command in T32 that is connected to a live target
or a T32 simulator that is loaded with a set of RAM dump to save the log into a tramp.txt file.


printer.file tramp.txt
wp.Var.View %o %i %hex tramp_log.index tramp_log.entries



For instance, the following sequence shows the handling of the SLEEP_TIMETICK_IRQ.


[0x2] = (event = TRAMP_LOG_EVENT_NEST_START = 0x0D, irq = TRAMP_NULL_IRQ =
0x0, timestamp = 0x03984FD0, level = TRAMP_LOG_LEVEL_0 = 0x0, in_stack =
0x1, in_service = 0x2),
[0x3] = (event = TRAMP_LOG_EVENT_ISR_START = 0x1, irq =
TRAMP_SLEEP_TIMETICK_IRQ = 0x25, timestamp = 0x03984FD0, level =
TRAMP_LOG_LEVEL_0 = 0x0, in_stack = 0x1, in_service = 0x2),
[0x4] = (event = TRAMP_LOG_EVENT_ISR_FINISH = 0x2, irq =
TRAMP_SLEEP_TIMETICK_IRQ = 0x25, timestamp = 0x03984FD1, level =
TRAMP_LOG_LEVEL_0 = 0x0, in_stack = 0x1, in_service = 0x2),
[0x5] = (event = TRAMP_LOG_EVENT_NEST_FINISH = 0x0E, irq = TRAMP_NULL_IRQ =
0x0, timestamp = 0x03984FD1, level = TRAMP_LOG_LEVEL_0 = 0x0, in_stack =
0x0, in_service = 0x0)



Besides tramp_log, tramp.table is a table that stores important information (such as ISR and some
debugging data including the last time the IRQ was handled and how many times it has fired,
etc.) about interrupts.


.2 Tramp GPIO log

For GPIO interrupt, tramp_gpio.log provides a log of the past 100 GPIO interrupts.


typedef struct
{
uint32 gpio;
uint32 timestamp;
} tramp_gpio_log_entry_type;
typedef struct
{
uint32 index;
tramp_gpio_log_entry_type entries[MAX_TRAMP_GPIO_LOG_ENTRIES];
} tramp_gpio_log_type;
typedef struct
{
boolean initialized;
tramp_gpio_data_type table[HAL_GPIOINT_NUM];
tramp_handler_type wakeup_isr;
#ifdef FEATURE_TRAMP_LOG
tramp_gpio_log_type log;

Sleep Mechanism in Qualcom msm8x55 chipset ---- Debugging Tips

This chapter provides some tips for debugging the sleep process. It covers the following topics:

? Shared memory log � smem_log is a very important tool for analyzing DEM and Sleep issues. It is written by both apps and modem systems and saved in shared memory region.

? Other logs � Other useful logs for debugging sleep issues include mao_trace, tramp_gpio, and tramp_log, etc.

? IRAM debugging � Since SDRAM needs to be put in Self-Refresh mode, the final stage of sleep process is executed in IRAM. We provide some tips on how to set breakpoints or adding log messages inside IRAM for debugging any issues inside IRAM.

? NV item � A couple of NV items related to power consumption


Shared memory log

The shared memory (SMEM) logging system provides a lightweight facility for logging events in the multiprocessor environment. It logs mainly sleep, DEM, and RPC events. This section discusses the implementation of smem log in AMSS, how to collect/read smem log, and some advise on inserting additional smem logs in software.


SMEM log in AMSS


Data structures

The smem log feature is guarded by the following compiler switch.


#define FEATURE_SMEM_LOG
There are three types of shared memory log areas.
/** Identifies the log areas available */
typedef enum {
/** Identifies the first log entry available. */
SMEM_LOG_AREA_FIRST,


/** The circular multiprocessor logging area is used by ONCRPC
and SMD. */
SMEM_LOG_AREA_CIRCULAR_MPROC = SMEM_LOG_AREA_FIRST,


/** The static logging area is used by initialization code. */
SMEM_LOG_AREA_STATIC,






/** The circular power logging area is used by power optimization. */
SMEM_LOG_AREA_CIRCULAR_POWER,


/** Identifies the number of log entries available. */
SMEM_LOG_AREA_COUNT
} smem_log_area;



The circular log contains ONCRPC, SMD, DEM, and sleep logs. The static log is used by
initialization code. The circular power log contains sleep and clock regime logs.

Each shared memory log event consists of timestamp, an event ID, and three 32-bit data values.
An extended smem log entry contains two log events, i.e., six data values.


/** The structure of a single log entry in shared memory. */
typedef struct {
/**
* The log entry identifier, consisting of the processor id,
* continuation number, subsystem id, and event id.
*
* - Bits 31-30 are processor ID: 10 => apps, 00 => modem, 01 =>
* qdsp6
* - Bits 29-28 are continuation number
* - Bits 27-16 are subsystem id (event base); see
* SMEM_LOG_*_EVENT_BASE
* - Bits 15-0 are event id
*
* Bit 28 is set for log entries are a continuation of the previous
* log entry, allowing more data to be written in a single
* transaction. In the current implementation, bit 29 is reserved.
*
* The subsystem id and event id uniquely identify a log entry type,
* and dictate the identity of their arguments.
*/
uint32 identifier;


/**
* The log entry timestamp, from the 32 kHz timetick.
*/
uint32 timetick;


/** The first word of data provided by the user. */
uint32 data1;


/** The second word of data provided by the user. */
uint32 data2;





/** The third word of data provided by the user. */
uint32 data3;
} smem_log_struct_type;



The smem logs are stored in the following table.


/* Static and runtime configuration for SMEM log areas */
typedef struct {
/* Static configuration: Is this log static or circular? */
enum {
SMEM_LOG_TYPE_STATIC,
SMEM_LOG_TYPE_CIRCULAR
} smem_log_type;


/* Static configuration: Is this log area to be readable from
* software?
*/
enum {
SMEM_LOG_WRITEONLY,
SMEM_LOG_READWRITE
} smem_log_readable;


/* Static configuration: The number of entries in this. Defaults to
* SMEM_LOG_NUM_ENTRIES. */
uint32 smem_num_entries;


/* Static configuration: The smem entry that contains the event
* table */
smem_mem_type smem_entry_events;


/* Static configuration: The smem entry that contains the index
* of the next log entry */
smem_mem_type smem_entry_idx;


/* Static configuration: The smem entry that contains the number
* of times the log has wrapped, or SMEM_INVALID if this is the
* existing shared memory log and this information is not
* available. */
smem_mem_type smem_entry_wrap;


/* Static configuration: The spinlock to acquire while updating
* this log area. */
uint32 smem_log_spinlock;





/* Runtime state: Pointer to the shared memory location for the
* event table. */
volatile smem_log_struct_type *smem_log_events;


/* Runtime state: Pointer to the shared memory location for the
* index of the next log entry. */
volatile uint32 *smem_log_write_idx;


/* Runtime state: Pointer to the shared memory location for the
* number of times the log has wrapped, or NULL if the
* information is not available. */
volatile uint32 *smem_log_write_wrap;


/* Runtime state: The index of the next log entry to read. Local
* to each processor. */
uint32 smem_log_read_idx;


/* Runtime state: The number of times the read index has wrapped
* past the end of the buffer. */
uint32 smem_log_read_wrap;
} smem_log_table_type;
static smem_log_table_type smem_log_table[SMEM_LOG_AREA_COUNT] = {
/* SMEM_LOG_AREA_CIRCULAR_MPROC */
{
/* This log must be circular or the static log rollover in
* smem_log_event and smem_log_event6 will recurse infinitely. */
SMEM_LOG_TYPE_CIRCULAR, /* smem_log_type */
SMEM_LOG_READWRITE, /* smem_log_readable */
SMEM_LOG_NUM_ENTRIES, /* smem_num_entries */
SMEM_SMEM_LOG_EVENTS, /* smem_entry_events */
SMEM_SMEM_LOG_IDX, /* smem_entry_idx */
SMEM_SMEM_LOG_MPROC_WRAP, /* smem_entry_wrap */
SMEM_SPINLOCK_SMEM_LOG, /* smem_log_spinlock */
},
/* SMEM_LOG_AREA_STATIC */
{
SMEM_LOG_TYPE_STATIC, /* smem_log_type */
SMEM_LOG_READWRITE, /* smem_log_readable */
SMEM_STATIC_LOG_NUM_ENTRIES, /* smem_num_entries */
SMEM_SMEM_STATIC_LOG_EVENTS, /* smem_entry_events */
SMEM_SMEM_STATIC_LOG_IDX, /* smem_entry_idx */
SMEM_INVALID, /* smem_entry_wrap */
SMEM_SPINLOCK_STATIC_LOG, /* smem_log_spinlock */

                };                                                       
                                                                         
               },                                                        
               /* SMEM_LOG_AREA_CIRCULAR_POWER */                        
/* smem_log_rea{                                                         dable */ SMEM_LOG_NUM_ENTRIES, /* smem_num_entries */ SMEM_SMEM_LOG_POWER_EVENTS, /* smem_entry_events */ SMEM_SMEM_LOG_POWER_IDX, /* smem_entry_idx */ SMEM_SMEM_LOG_POWER_WRAP, /* smem_entry_wrap */ SMEM_SPINLOCK_SMEM_LOG, /* smem_log_spinlock */      
               SMEM_LOG_TYPE_CIRCULAR, /* smem_log_type */ SMEM_LOG_READWRITE, 
               },