Пример #1
0
void sunxi_pwm_get_sys_config(int pwm)
{
    int ret, val;
    char primary_key[25];
    user_gpio_set_t gpio_info[1];

    sprintf(primary_key, "pwm%d_para", pwm);
    ret = script_parser_fetch(primary_key, "pwm_used", &val, 1);
    if(ret < 0) {
        pwm_debug("fetch script data fail\n");
        } else {
            if(val == 1) {
                ret = script_parser_fetch(primary_key, "pwm_positive", (int *)&gpio_info, sizeof(user_gpio_set_t) / sizeof(int));
                if(ret < 0) {
                    pwm_debug("fetch script data fail\n");
                    } else {
                        pwm_pin_count[pwm]++;
                        memcpy(&pwm_gpio_info[pwm][0], gpio_info, sizeof(user_gpio_set_t));
                        }

                ret = script_parser_fetch(primary_key, "pwm_negative", (int *)&gpio_info, sizeof(user_gpio_set_t) / sizeof(int));
                if(ret < 0) {
                    pwm_debug("fetch script data fail\n");
                    } else {
                        pwm_pin_count[pwm]++;
                        memcpy(&pwm_gpio_info[pwm][1], gpio_info, sizeof(user_gpio_set_t));
                        }
                }
            }
}
Пример #2
0
void sunxi_pwm_disable(int pwm)
{
    uint temp;

#ifndef PWM_FPGA

    int i;
    uint ret = 0;

    for(i = 0; i < pwm_pin_count[pwm]; i++) {
        ret = gpio_request(&pwm_gpio_info[pwm][i], 1);
        if(ret == 0) {
            pwm_debug("pwm gpio request failed!\n");
        }

        gpio_release(ret, 2);
    }

    #endif

#if ((defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN9IW1P1))

    temp = sunxi_pwm_read_reg(pwm * 0x10);

    temp &= ~(1 << 4);
    temp &= ~(1 << 6);

    sunxi_pwm_write_reg(pwm * 0x10, temp);

#elif (defined CONFIG_ARCH_SUN8IW3P1 || (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN8IW6P1) || (defined CONFIG_ARCH_SUN8IW7P1) || (defined CONFIG_ARCH_SUN8IW8P1)||(defined CONFIG_ARCH_SUN8IW9P1))

    temp = sunxi_pwm_read_reg(0);

    if(pwm == 0) {
        temp &= ~(1 << 4);
        temp &= ~(1 << 6);
        } else {
            temp &= ~(1 << 19);
            temp &= ~(1 << 21);
            }

#elif (defined CONFIG_ARCH_SUN7I) || (defined CONFIG_ARCH_SUN5I)

	temp = sunxi_pwm_read_reg(0x200);

	 if(pwm == 0) {
	    temp &= ~(1 << 4);
	    temp &= ~(1 << 6);
	    } else {
	        temp &= ~(1 << 19);
	        temp &= ~(1 << 21);
	        }

	sunxi_pwm_write_reg(0x200, temp);

#endif
}
Пример #3
0
int sunxi_pwm_enable(int pwm)
{
    uint temp;

#ifndef CONFIG_FPGA_V4_PLATFORM

    int i;
    uint ret = 0;

    for(i = 0; i < pwm_pin_count[pwm]; i++) {
        ret = gpio_request(&pwm_gpio_info[pwm][i], 1);
        if(ret == 0) {
            pwm_debug("pwm gpio request failed!\n");
        }

        gpio_release(ret, 2);
    }

#endif

#if ((defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN9IW1P1))

    temp = sunxi_pwm_read_reg(pwm * 0x10);

    temp |= 1 << 4;
    temp |= 1 << 6;

    sunxi_pwm_write_reg(pwm * 0x10, temp);

#elif ((defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN7IW1P1))

    temp = sunxi_pwm_read_reg(0);

    if(pwm == 0) {
        temp |= 1 << 4;
        temp |= 1 << 6;
        } else {
            temp |= 1 << 19;
            temp |= 1 << 21;
            }

    sunxi_pwm_write_reg(0, temp);

#endif

    return 0;
}
Пример #4
0
static int sunxi_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
		int duty_ns, int period_ns)
{
    #if ((defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN9IW1P1))

    __u32 pre_scal[7] = {1, 2, 4, 8, 16, 32, 64};
    __u32 freq;
    __u32 pre_scal_id = 0;
    __u32 entire_cycles = 256;
    __u32 active_cycles = 192;
    __u32 entire_cycles_max = 65536;
    __u32 temp;
    __u32 calc;

    if(period_ns < 10667)
        freq = 93747;
    else if(period_ns > 174762666) {
        freq = 6;
        calc = period_ns / duty_ns;
        duty_ns = 174762666 / calc;
        period_ns = 174762666;
        }
    else
        freq = 1000000000 / period_ns;

    entire_cycles = 24000000 / freq /pre_scal[pre_scal_id];

    while(entire_cycles > entire_cycles_max) {
        pre_scal_id++;

        if(pre_scal_id > 6)
            break;

        entire_cycles = 24000000 / freq / pre_scal[pre_scal_id];
        }

    if(period_ns < 5*100*1000)
        active_cycles = (duty_ns * entire_cycles + (period_ns/2)) /period_ns;
    else if(period_ns >= 5*100*1000 && period_ns < 6553500)
        active_cycles = ((duty_ns / 100) * entire_cycles + (period_ns /2 / 100)) / (period_ns/100);
    else
        active_cycles = ((duty_ns / 10000) * entire_cycles + (period_ns /2 / 10000)) / (period_ns/10000);

    temp = sunxi_pwm_read_reg(pwm->pwm * 0x10);

    temp = (temp & 0xfffffff0) | pre_scal_id;

    sunxi_pwm_write_reg(pwm->pwm * 0x10, temp);

    sunxi_pwm_write_reg(pwm->pwm * 0x10 + 0x04, ((entire_cycles - 1)<< 16) | active_cycles);

    pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp);


    #elif defined(CONFIG_ARCH_SUN8IW3P1) || defined(CONFIG_ARCH_SUN8IW5P1) || defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN8IW9P1) || defined(CONFIG_ARCH_SUN8IW8P1)

    __u32 pre_scal[11][2] = {{15, 1}, {0, 120}, {1, 180}, {2, 240}, {3, 360}, {4, 480}, {8, 12000}, {9, 24000}, {10, 36000}, {11, 48000}, {12, 72000}};
    __u32 freq;
    __u32 pre_scal_id = 0;
    __u32 entire_cycles = 256;
    __u32 active_cycles = 192;
    __u32 entire_cycles_max = 65536;
    __u32 temp;

	if(period_ns < 42) {
		/* if freq lt 24M, then direct output 24M clock */
		temp = sunxi_pwm_read_reg(pwm->pwm * 0x10);
		temp |= (0x1 << 9);//pwm bypass
		sunxi_pwm_write_reg(pwm->pwm * 0x10, temp);

		return 0;
	}

    if(period_ns < 10667)
        freq = 93747;
    else if(period_ns > 1000000000)
        freq = 1;
    else
        freq = 1000000000 / period_ns;

    entire_cycles = 24000000 / freq / pre_scal[pre_scal_id][1];

    while(entire_cycles > entire_cycles_max) {
        pre_scal_id++;

        if(pre_scal_id > 10)
            break;

        entire_cycles = 24000000 / freq / pre_scal[pre_scal_id][1];
        }

    if(period_ns < 5*100*1000)
        active_cycles = (duty_ns * entire_cycles + (period_ns/2)) /period_ns;
    else if(period_ns >= 5*100*1000 && period_ns < 6553500)
        active_cycles = ((duty_ns / 100) * entire_cycles + (period_ns /2 / 100)) / (period_ns/100);
    else
        active_cycles = ((duty_ns / 10000) * entire_cycles + (period_ns /2 / 10000)) / (period_ns/10000);

    temp = sunxi_pwm_read_reg(0);

    if(pwm->pwm == 0)
        temp = (temp & 0xfffffff0) |pre_scal[pre_scal_id][0];
    else
        temp = (temp & 0xfff87fff) |pre_scal[pre_scal_id][0];

    sunxi_pwm_write_reg(0, temp);

    sunxi_pwm_write_reg((pwm->pwm + 1)  * 0x04, ((entire_cycles - 1)<< 16) | active_cycles);

    pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp);

    #endif

    return 0;
}
Пример #5
0
int sunxi_pwm_config(int pwm, int duty_ns, int period_ns)
{
#if ((defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN9IW1P1))

    uint pre_scal[7] = {1, 2, 4, 8, 16, 32, 64};
    uint freq;
    uint pre_scal_id = 0;
    uint entire_cycles = 256;
    uint active_cycles = 192;
    uint entire_cycles_max = 65536;
    uint temp;
    uint calc;

    if(period_ns < 10667)
        freq = 93747;
    else if(period_ns > 174762666) {
        freq = 6;
        calc = period_ns / duty_ns;
        duty_ns = 174762666 / calc;
        period_ns = 174762666;
        }
    else
        freq = 1000000000 / period_ns;

    entire_cycles = 24000000 / freq /pre_scal[pre_scal_id];

    while(entire_cycles > entire_cycles_max) {
        pre_scal_id++;

        if(pre_scal_id > 6)
            break;

        entire_cycles = 24000000 / freq / pre_scal[pre_scal_id];
        }

    if(period_ns < 5*100*1000)
        active_cycles = (duty_ns * entire_cycles + (period_ns/2)) /period_ns;
    else if(period_ns >= 5*100*1000 && period_ns < 6553500)
        active_cycles = ((duty_ns / 100) * entire_cycles + (period_ns /2 / 100)) / (period_ns/100);
    else
        active_cycles = ((duty_ns / 10000) * entire_cycles + (period_ns /2 / 10000)) / (period_ns/10000);

    temp = sunxi_pwm_read_reg(pwm * 0x10);

    temp = (temp & 0xfffffff0) | pre_scal_id;

    sunxi_pwm_write_reg(pwm * 0x10, temp);

    sunxi_pwm_write_reg(pwm * 0x10 + 0x04, ((entire_cycles - 1)<< 16) | active_cycles);

    pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp);


#elif (defined CONFIG_ARCH_SUN8IW3P1 ||  (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN8IW6P1))

    uint pre_scal[11][2] = {{15, 1}, {0, 120}, {1, 180}, {2, 240}, {3, 360}, {4, 480}, {8, 12000}, {9, 24000}, {10, 36000}, {11, 48000}, {12, 72000}};
    uint freq;
    uint pre_scal_id = 0;
    uint entire_cycles = 256;
    uint active_cycles = 192;
    uint entire_cycles_max = 65536;
    uint temp;

    if(period_ns < 10667)
        freq = 93747;
    else if(period_ns > 1000000000)
        freq = 1;
    else
        freq = 1000000000 / period_ns;

    entire_cycles = 24000000 / freq / pre_scal[pre_scal_id][1];

    while(entire_cycles > entire_cycles_max) {
        pre_scal_id++;

        if(pre_scal_id > 10)
            break;

        entire_cycles = 24000000 / freq / pre_scal[pre_scal_id][1];
        }

    if(period_ns < 5*100*1000)
        active_cycles = (duty_ns * entire_cycles + (period_ns/2)) /period_ns;
    else if(period_ns >= 5*100*1000 && period_ns < 6553500)
        active_cycles = ((duty_ns / 100) * entire_cycles + (period_ns /2 / 100)) / (period_ns/100);
    else
        active_cycles = ((duty_ns / 10000) * entire_cycles + (period_ns /2 / 10000)) / (period_ns/10000);

    temp = sunxi_pwm_read_reg(0);

    if(pwm == 0)
        temp = (temp & 0xfffffff0) |pre_scal[pre_scal_id][0];
    else
        temp = (temp & 0xfff87fff) |pre_scal[pre_scal_id][0];

    sunxi_pwm_write_reg(0, temp);

    sunxi_pwm_write_reg((pwm + 1)  * 0x04, ((entire_cycles - 1)<< 16) | active_cycles);

    pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp);

#elif (defined CONFIG_ARCH_SUN7I) || (defined CONFIG_ARCH_SUN5I)

   __u32 pre_scal[10] = {120, 180, 240, 360, 480, 12000, 24000, 36000, 48000, 72000};
    __u32 pre_scal_id = 0, entire_cycle = 256, active_cycle = 192;
    __u32 i=0, tmp=0;
    __u32 freq;

    freq = 1000000000 /period_ns;

    if(freq > 200000)
    {
        pwm_debug("pwm preq is large then 200khz, fix to 200khz\n");
        freq = 200000;
    }

    if(freq > 781)
    {
        pre_scal_id = 0;
        entire_cycle = (24000000 / pre_scal[pre_scal_id] + (freq/2)) / freq;
        pwm_debug("pre_scal:%d, entire_cycle:%d, pwm_freq:%d\n", pre_scal[i], entire_cycle, 24000000 / pre_scal[pre_scal_id] / entire_cycle );
    }
    else
    {
    	for(i=0; i<10; i++)
    	{
	        __u32 pwm_freq = 0;

	        pwm_freq = 24000000 / (pre_scal[i] * 256);
	        if((abs((pwm_freq) - (freq))) < (abs((tmp) - (freq))))
	        {
	            tmp = pwm_freq;
	            pre_scal_id = i;
	            entire_cycle = 256;
                pwm_debug("pre_scal:%d, entire_cycle:%d, pwm_freq:%d\n", pre_scal[i], 256, pwm_freq);
                pwm_debug("----%d\n", tmp);
	        }
    	}
	}
    active_cycle = (duty_ns * entire_cycle + (period_ns/2)) /period_ns;

if(pre_scal_id >= 5)
    {
        pre_scal_id += 3;
    }

    if(pwm == 0)
    {
        sunxi_pwm_write_reg(0x204, ((entire_cycle - 1)<< 16) | active_cycle);

        tmp = sunxi_pwm_read_reg(0x200) & 0xfffffff0;
        tmp |=  pre_scal_id;//bit6:gatting the special clock for pwm0; bit5:pwm0  active state is high level
        sunxi_pwm_write_reg(0x200,tmp);
    }
    else
    {
        sunxi_pwm_write_reg(0x208, ((entire_cycle - 1)<< 16) | active_cycle);

        tmp = sunxi_pwm_read_reg(0x200) & 0xfff87fff;
        tmp |=  (pre_scal_id<<15);//bit21:gatting the special clock for pwm1; bit20:pwm1  active state is high level
        sunxi_pwm_write_reg(0x200,tmp);
    }

    pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp);

#endif

    return 0;
}
Пример #6
0
int sunxi_pwm_config(int pwm, int duty_ns, int period_ns)
{
#if ((defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN9IW1P1))

    uint pre_scal[7] = {1, 2, 4, 8, 16, 32, 64};
    uint freq;
    uint pre_scal_id = 0;
    uint entire_cycles = 256;
    uint active_cycles = 192;
    uint entire_cycles_max = 65536;
    uint temp;
    uint calc;

    if(period_ns < 10667)
        freq = 93747;
    else if(period_ns > 174762666) {
        freq = 6;
        calc = period_ns / duty_ns;
        duty_ns = 174762666 / calc;
        period_ns = 174762666;
        }
    else
        freq = 1000000000 / period_ns;

    entire_cycles = 24000000 / freq /pre_scal[pre_scal_id];

    while(entire_cycles > entire_cycles_max) {
        pre_scal_id++;

        if(pre_scal_id > 6)
            break;

        entire_cycles = 24000000 / freq / pre_scal[pre_scal_id];
        }

    if(period_ns < 5*100*1000)
        active_cycles = (duty_ns * entire_cycles + (period_ns/2)) /period_ns;
    else if(period_ns >= 5*100*1000 && period_ns < 6553500)
        active_cycles = ((duty_ns / 100) * entire_cycles + (period_ns /2 / 100)) / (period_ns/100);
    else
        active_cycles = ((duty_ns / 10000) * entire_cycles + (period_ns /2 / 10000)) / (period_ns/10000);

    temp = sunxi_pwm_read_reg(pwm * 0x10);

    temp = (temp & 0xfffffff0) | pre_scal_id;

    sunxi_pwm_write_reg(pwm * 0x10, temp);

    sunxi_pwm_write_reg(pwm * 0x10 + 0x04, ((entire_cycles - 1)<< 16) | active_cycles);

    pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp);


#elif ((defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN7IW1P1))
	tick_printf("+++++++++++++++++++test10+++++++++++++++++++++\n");	

    uint pre_scal[11][2] = {{15, 1}, {0, 120}, {1, 180}, {2, 240}, {3, 360}, {4, 480}, {8, 12000}, {9, 24000}, {10, 36000}, {11, 48000}, {12, 72000}};
    uint freq;
    uint pre_scal_id = 0;
    uint entire_cycles = 256;
    uint active_cycles = 192;
    uint entire_cycles_max = 65536;
    uint temp;

    if(period_ns < 10667)
        freq = 93747;
    else if(period_ns > 1000000000)
        freq = 1;
    else
        freq = 1000000000 / period_ns;

    entire_cycles = 24000000 / freq / pre_scal[pre_scal_id][1];

    while(entire_cycles > entire_cycles_max) {
        pre_scal_id++;

        if(pre_scal_id > 10)
            break;

        entire_cycles = 24000000 / freq / pre_scal[pre_scal_id][1];
        }

    if(period_ns < 5*100*1000)
        active_cycles = (duty_ns * entire_cycles + (period_ns/2)) /period_ns;
    else if(period_ns >= 5*100*1000 && period_ns < 6553500)
        active_cycles = ((duty_ns / 100) * entire_cycles + (period_ns /2 / 100)) / (period_ns/100);
    else
        active_cycles = ((duty_ns / 10000) * entire_cycles + (period_ns /2 / 10000)) / (period_ns/10000);

    temp = sunxi_pwm_read_reg(0);

    if(pwm == 0)
        temp = (temp & 0xfffffff0) |pre_scal[pre_scal_id][0];
    else
        temp = (temp & 0xfff87fff) |pre_scal[pre_scal_id][0];

    sunxi_pwm_write_reg(0, temp);

    sunxi_pwm_write_reg((pwm + 1)  * 0x04, ((entire_cycles - 1)<< 16) | active_cycles);

    pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp);

#endif

    return 0;
}