Beispiel #1
0
static int
msmrtc_suspend(struct platform_device *dev, pm_message_t state)
{
	unsigned secs;
	struct msm_dex_command dex;
	if (rtcalarm_time) {
		unsigned long now = msmrtc_get_seconds();
		int diff = rtcalarm_time - now;
		if (diff <= 0) {
			msmrtc_alarmtimer_expired(1);
			return 0;
		}

		if(max_diff)
			diff = max_diff;

		dex.cmd = PCOM_READ_RTC;
		msm_proc_comm_wince(&dex, &secs);

		printk("Wake up in %d seconds\n",diff);

		dex.cmd = PCOM_SET_ALARM_RTC;
		dex.has_data = 1;
		dex.data = secs + diff;
		msm_proc_comm_wince(&dex, 0);
	}

	return 0;
}
void msm_proc_comm_wince_vibrate(uint32_t val)
{
	struct msm_dex_command vibra;

	if (val == 0) {
		vibra.cmd = PCOM_VIBRA_OFF;
		msm_proc_comm_wince(&vibra, 0);
	} else if (val > 0) {
		if (val == 1 || val > 0xb22)
			val = 0xb22;
		writel(val, MSM_SHARED_RAM_BASE + 0xfc130);
		vibra.cmd = PCOM_VIBRA_ON;
		msm_proc_comm_wince(&vibra, 0);
	}
}
Beispiel #3
0
int vreg_enable(struct vreg *vreg)
{
	unsigned id = vreg->id;

	printk("[%s] vreg->id=%d\n", __func__, id);
	return 0;

#if defined(CONFIG_MSM_AMSS_VERSION_WINCE)
	struct msm_dex_command dex;
	id = 1U << id;
	dex.cmd = PCOM_PMIC_REG_ON;
	dex.has_data = 1;
	dex.data = id;
	if (vreg->refcnt == 0)
		vreg->status = msm_proc_comm_wince(&dex, 0);
#else
	unsigned enable = 1;
	if (vreg->refcnt == 0)
		vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
#endif

	if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
		vreg->refcnt++;

	if (debug_mask & VREG_DEBUG_SWITCH)
		printk(KERN_DEBUG "%s: n=%s id=%u s=%d ref=%u\n", __func__,
			vreg->name, vreg->id, vreg->status, vreg->refcnt);

	return vreg->status;
}
static void msm_proc_comm_wince_late_resume(struct early_suspend *h) {
	struct msm_dex_command dex;
	printk("Sending arm9_low_speed 7\n");
	dex.cmd = PCOM_ARM9_LOW_SPEED;
	dex.has_data = 1;
	dex.data = 7;
	msm_proc_comm_wince(&dex, 0);
}
Beispiel #5
0
static int
msmrtc_pmlib_read_time(struct device *dev, struct rtc_time *tm)
{
	unsigned secs;
	struct msm_dex_command dex;

	dex.cmd = PCOM_READ_RTC;
	msm_proc_comm_wince(&dex, &secs);
	secs = secs + SECSFROM_1970_TO_1980;	// MSM RTC starts 10 years after unix time
	rtc_time_to_tm(secs, tm);
	return 0;
}
Beispiel #6
0
int msmrtc_rewake(int diff)
{
	unsigned secs;
	struct msm_dex_command dex;

	
	dex.cmd = PCOM_READ_RTC;
	msm_proc_comm_wince(&dex, &secs);

	if(diff)
	{
//		printk("Wake up in %d seconds\n",diff);

		dex.cmd = PCOM_SET_ALARM_RTC;
		dex.has_data = 1;
		dex.data = secs + diff;
		msm_proc_comm_wince(&dex, 0);
	}

	return 0;
}
static int update_codec_table(void __user * arg)
{
	struct msm_dex_command dex = {
		.cmd = PCOM_UPDATE_AUDIO,
		.has_data = 1,
		.data = DEX_UPDATE_VOC,
	};
	struct htc_voc_cal_table table;
	uint16_t *table_array;
	int rc = -EIO;

	if (copy_from_user(&table, arg, sizeof(table))) {
		ERR_COPY_FROM_USER();
		return -EFAULT;
	} else {
		D("%s : table size = %d\n", __func__, table.size);
		table_array = kmalloc(table.size, GFP_ATOMIC);
		if (table_array != NULL) {
			if (copy_from_user
			    (table_array, table.pArray, table.size)) {
				ERR_COPY_FROM_USER();
				rc = -EFAULT;
				goto free_exit;
			}
            memcpy(amss_data->codec_table, table_array, table.size);
	        msm_proc_comm_wince(&dex,0);
			rc = 0;
		}
	}

 free_exit:
	if (table_array != NULL) {
		kfree(table_array);
	}
	return rc;
}

/* Adie updates */
static void ADIE_Force8k(bool bOn) {
    int adie = readl(MSM_SHARED_RAM_BASE + 0xfc0d0);
    if (bOn) {
        adie |= 0x1;
    } else {
        adie &= ~0x1;
    }
    writel(adie, MSM_SHARED_RAM_BASE + 0xfc0d0);
}
Beispiel #8
0
static int
msmrtc_pmlib_set_time(struct device *dev, struct rtc_time *tm)
{
	unsigned long unix_time;
	struct msm_dex_command dex;

	if (rtc_valid_tm(tm))
		return -EINVAL;

	rtc_tm_to_time(tm, &unix_time);
	unix_time=unix_time-SECSFROM_1970_TO_1980; // MSM RTC starts 10 years after unix time

	dex.cmd = PCOM_WRITE_RTC;
	dex.has_data = 1;
	dex.data = unix_time;
	msm_proc_comm_wince(&dex, 0);

	return 0;
}
static int htc_get_batt_smem_info(struct battery_info_reply *buffer)
{
	volatile struct htc_batt_info_u16 *batt_16 = NULL;
	struct msm_dex_command dex;
	
	//send DEX to update smem values
	dex.cmd = PCOM_GET_BATTERY_DATA;
	msm_proc_comm_wince(&dex, 0);
	mutex_lock(&htc_batt_info.lock);

	//now read latest values
	batt_16 = (void *)(MSM_SHARED_RAM_BASE + htc_batt_info.resources->smem_offset);
	buffer->batt_vol = batt_16->batt_vol;
	buffer->batt_current = batt_16->batt_charge;
	buffer->batt_tempRAW = batt_16->batt_temp;
	buffer->batt_id = batt_16->batt_id;
	buffer->batt_discharge = batt_16->batt_discharge;
	//printBattBuff(buffer,"RAW VALUES");
	
	return 0;
}
static int get_battery_id_detection( struct battery_info_reply *buffer ) {
	u32 batt_id;
	struct msm_dex_command dex;

	dex.cmd = PCOM_GET_BATTERY_ID;
	msm_proc_comm_wince( &dex, 0 );

	batt_id = GET_BATT_ID;

	/* buffer->batt_id will be overwritten on next battery reading so we can use it as
	 * a temp variable to pass it to machine specific battery detection
	 */
	buffer->batt_id = batt_id;
	// apply the adc range correction
	buffer->batt_id = ( buffer->batt_id * 0xA28 ) / htc_adc_range;  
        //photon batt capacity = 1200Mah
	buffer->full_bat = 1200000;

	//update battery params
	batt_param = (struct sBattery_Parameters*) sBatParams_photon[0];	
	return 0;
}
Beispiel #11
0
int vreg_set_level(struct vreg *vreg, unsigned mv)
{
	unsigned id = vreg->id;

#if defined(CONFIG_MSM_AMSS_VERSION_WINCE)
	struct msm_dex_command dex = { 
		.cmd = PCOM_PMIC_REG_VOLTAGE,
		.has_data = 1, 
		.data = (1U << id) };
	// This reg appears to only be used by vreg_set_level()
	writel(mv, MSM_SHARED_RAM_BASE + 0xfc130);
	vreg->status = msm_proc_comm_wince(&dex, 0);
#else
	vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
#endif

	if (debug_mask & VREG_DEBUG_LEVEL)
		printk(KERN_DEBUG "%s: n=%s id=%u s=%d ref=%u -> %umv\n", __func__,
			vreg->name, vreg->id, vreg->status, vreg->refcnt, mv);

	return vreg->status;
}

#if defined(CONFIG_DEBUG_FS)

static int vreg_debug_set(void *data, u64 val)
{
	struct vreg *vreg = data;
	switch (val) {
	case 0:
		vreg_disable(vreg);
		break;
	case 1:
		vreg_enable(vreg);
		break;
	default:
		vreg_set_level(vreg, val);
		break;
	}
	return 0;
}

static int vreg_debug_get(void *data, u64 *val)
{
	struct vreg *vreg = data;

	if (!vreg->status)
		*val = 0;
	else
		*val = 1;

	return 0;
}

static int vreg_debug_count_set(void *data, u64 val)
{
	struct vreg *vreg = data;
	if (val > UINT_MAX)
		val = UINT_MAX;
	vreg->refcnt = val;
	return 0;
}

static int vreg_debug_count_get(void *data, u64 *val)
{
	struct vreg *vreg = data;

	*val = vreg->refcnt;

	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
			vreg_debug_count_set, "%llu\n");

static int __init vreg_debug_init(void)
{
	struct dentry *dent;
	int n;
	char name[32];
	const char *refcnt_name = "_refcnt";

	dent = debugfs_create_dir("vreg", 0);
	if (IS_ERR(dent))
		return 0;

	for (n = 0; n < ARRAY_SIZE(vregs); n++) {
		(void) debugfs_create_file(vregs[n].name, 0644,
					   dent, vregs + n, &vreg_fops);

		strlcpy(name, vregs[n].name, sizeof(name));
		strlcat(name, refcnt_name, sizeof(name));
		(void) debugfs_create_file(name, 0644,
					   dent, vregs + n, &vreg_count_fops);
	}

	return 0;
}

device_initcall(vreg_debug_init);
static int dex_update_audio(int data)
{
	struct msm_dex_command dex = {
		.cmd = PCOM_UPDATE_AUDIO,
		.has_data = 1,
		.data = data,
	};

	msm_proc_comm_wince(&dex, 0);

	return 0;
}

static int dex_update_audio_done(void) {
	struct msm_dex_command dex = {
		.cmd = PCOM_UPDATE_AUDIO,
		.has_data = 1,
		.data = DEX_AUDIO_DONE,
	};
	D("%s\n", __func__);
	return msm_proc_comm_wince(&dex, 0);
}

static int update_audio_setting(void __user *arg)
{
    int ret = -EFAULT;
    struct audio_update_req req;

	if (copy_from_user(&req, arg, sizeof(struct audio_update_req))) {
		ERR_COPY_FROM_USER();
		return -EFAULT;
	} else {
        switch (req.type) {
            case PCOM_UPDATE_REQ:
                ret = dex_update_audio(req.value);
            break;

            case ADIE_FORCE8K_REQ:
                ADIE_Force8k( (req.value)?true:false );
                ret = 0;
            break;

            case ADIE_FORCE_ADIE_AWAKE_REQ:
                ADIE_ForceADIEAwake( (req.value)?true:false );
                ret = 0;
            break;

            case ADIE_FORCE_ADIE_UPDATE_REQ:
                ADIE_ForceADIEUpdate( (req.value)?true:false );
                ret = 0;
            break;

            case ADIE_UPDATE_AUDIO_METHOD:
                ADIE_UpdateAudioMethod( (req.value)?true:false );
                ret = 0;
            break;

            default:
            break;
        }
    }
    return ret;
}

static int turn_mic_bias_on_internal(bool on, bool bDualMicEn)
{
	char pmSpeakerGain[2][10] = { 
			{0x93, 0, 0x93, 7, 0x93, 1, 0x93, 7, 0xFF, 0xFF},
			{0x93, 0, 0x93, 4, 0x93, 1, 0x93, 4, 0xFF, 0xFF} };


	D("%s(%d)\n", __func__, on);

	/* enable handset mic */
/* r0bin: photon doesnt have mic offset, or at least it wasnt found yet. 
 * uncomment those line is safe, we enable mic with pmic_en below
 *
	if ( machine_is_htcrhodium() && bDualMicEn && on ) {
		memcpy(amss_data->mic_offset, pmSpeakerGain[1], 10);
	} else {
		writel(0xffff0080 | (on ? 0x100 : 0), amss_data->mic_offset);   
	}
	dex_update_audio_done();

	if ( machine_is_htcrhodium() ) {
		if ( bDualMicEn && on ) {
			ADC3001_wakeup();
		} else {
			ADC3001_powerdown();
		}
	}
*/
	if (amss_data->mic_bias_callback)
		amss_data->mic_bias_callback(on);

	dex_update_audio_done();
	
	return 0;
}
static int dex_update_audio(int data)
{
	struct msm_dex_command dex = {
		.cmd = PCOM_UPDATE_AUDIO,
		.has_data = 1,
		.data = data,
	};

	msm_proc_comm_wince(&dex, 0);

	return 0;
}

static int dex_update_audio_done(void) {
	struct msm_dex_command dex = {
		.cmd = PCOM_UPDATE_AUDIO,
		.has_data = 1,
		.data = DEX_AUDIO_DONE,
	};
	D("%s\n", __func__);
	return msm_proc_comm_wince(&dex, 0);
}

static int update_audio_setting(void __user *arg)
{
    int ret = -EFAULT;
    struct audio_update_req req;

	if (copy_from_user(&req, arg, sizeof(struct audio_update_req))) {
		ERR_COPY_FROM_USER();
		return -EFAULT;
	} else {
        switch (req.type) {
            case PCOM_UPDATE_REQ:
                ret = dex_update_audio(req.value);
            break;

            case ADIE_FORCE8K_REQ:
                ADIE_Force8k( (req.value)?true:false );
                ret = 0;
            break;

            case ADIE_FORCE_ADIE_AWAKE_REQ:
                ADIE_ForceADIEAwake( (req.value)?true:false );
                ret = 0;
            break;

            case ADIE_FORCE_ADIE_UPDATE_REQ:
                ADIE_ForceADIEUpdate( (req.value)?true:false );
                ret = 0;
            break;

            case ADIE_UPDATE_AUDIO_METHOD:
                ADIE_UpdateAudioMethod( (req.value)?true:false );
                ret = 0;
            break;

            default:
            break;
        }
    }
    return ret;
}

static int turn_mic_bias_on_internal(bool on, bool bDualMicEn)
{
	if (amss_data->mic_bias_callback)
		amss_data->mic_bias_callback(on);

	dex_update_audio_done();
	
	return 0;
}

int turn_mic_bias_on(bool on)
{
	return turn_mic_bias_on_internal(on, false);
}
EXPORT_SYMBOL(turn_mic_bias_on);

static int update_hw_audio_path(void __user *arg)
{
	struct msm_audio_path audio_path;

	if (copy_from_user(&audio_path, arg, sizeof(audio_path))) {
		ERR_COPY_FROM_USER();
		return -EFAULT;
	}

	D("%s: mic=%d, dual_mic=%d, speaker=%d, headset = %d\n",
			__func__,
	       audio_path.enable_mic, audio_path.enable_dual_mic,
	       audio_path.enable_speaker, audio_path.enable_headset);

	/* Switch microphone on/off */
	turn_mic_bias_on_internal(audio_path.enable_mic,
                     audio_path.enable_dual_mic);

	/* Switch headset HW on/off */
	headphone_amp_power(audio_path.enable_headset);

	/* Switch Speaker HW on/off */
	speaker_amp_power(audio_path.enable_speaker);

	return 0;
}

static int acoustic_open(struct inode *inode, struct file *file)
{
	D("%s\n", __func__);
	return 0;
}