kernel_samsung_a34x-permissive/drivers/misc/mediatek/pwm/mtk_pwm.c

2009 lines
51 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <generated/autoconf.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/atomic.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/clk.h>
#include <mt-plat/mtk_pwm.h>
#include <mach/mtk_pwm_prv.h>
#include <mt-plat/mtk_pwm_hal_pub.h>
#include <mach/mtk_pwm_hal.h>
#define PWM_LDVT_FLAG 1
#if PWM_LDVT_FLAG
#include <linux/gpio.h>
#include <linux/pinctrl/consumer.h>
static u8 intr_pwm_nu[PWM_MAX];
#endif
#define T "[PWM]"
void __iomem *pwm_base;
struct mutex pwm_power_lock;
struct pwm_device {
const char *name;
atomic_t ref;
dev_t devno;
spinlock_t lock;
unsigned long power_flag;
struct device dev;
};
static struct pwm_device pwm_dat = {
.name = PWM_DEVICE,
.ref = ATOMIC_INIT(0),
.power_flag = 0,
.lock = __SPIN_LOCK_UNLOCKED(pwm_dat.lock)
};
static struct pwm_device *pwm_dev = &pwm_dat;
void mt_pwm_power_on(u32 pwm_no, bool pmic_pad)
{
mutex_lock(&pwm_power_lock);
mt_pwm_power_on_hal(pwm_no, pmic_pad, &(pwm_dev->power_flag));
mutex_unlock(&pwm_power_lock);
}
static void mt_pwm_power_off(u32 pwm_no, bool pmic_pad)
{
mutex_lock(&pwm_power_lock);
mt_pwm_power_off_hal(pwm_no, pmic_pad, &(pwm_dev->power_flag));
mutex_unlock(&pwm_power_lock);
}
static s32 mt_pwm_sel_pmic(u32 pwm_no)
{
unsigned long flags;
s32 ret;
struct pwm_device *dev = pwm_dev;
spin_lock_irqsave(&dev->lock, flags);
ret = mt_pwm_sel_pmic_hal(pwm_no);
spin_unlock_irqrestore(&dev->lock, flags);
if (ret == (-EEXCESSPWMNO))
pr_debug(T "PWM1~PWM4 not support pmic_pad\n");
return ret;
}
static s32 mt_pwm_sel_ap(u32 pwm_no)
{
unsigned long flags;
s32 ret;
struct pwm_device *dev = pwm_dev;
spin_lock_irqsave(&dev->lock, flags);
ret = mt_pwm_sel_ap_hal(pwm_no);
spin_unlock_irqrestore(&dev->lock, flags);
if (ret == (-EEXCESSPWMNO))
pr_debug(T "PWM1~PWM4 not support pmic_pad\n");
return ret;
}
/*******************************************************
* Set PWM_ENABLE register bit to enable pwm1~pwm7
*
********************************************************/
static s32 mt_set_pwm_enable(u32 pwm_no)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid!\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number is not between PWM1~PWM7\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_enable_hal(pwm_no);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
static s32 mt_set_pwm_disable(u32 pwm_no)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number is not between PWM1~PWM7\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_disable_hal(pwm_no);
spin_unlock_irqrestore(&dev->lock, flags);
mdelay(1);
return RSUCCESS;
}
void mt_pwm_disable(u32 pwm_no, u8 pmic_pad)
{
mt_set_pwm_disable(pwm_no);
mt_pwm_power_off(pwm_no, pmic_pad);
}
void mt_set_pwm_enable_seqmode(void)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_enable_seqmode_hal();
spin_unlock_irqrestore(&dev->lock, flags);
}
void mt_set_pwm_disable_seqmode(void)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_disable_seqmode_hal();
spin_unlock_irqrestore(&dev->lock, flags);
}
s32 mt_set_pwm_test_sel(u32 val)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not pwm_dev\n");
return -EINVALID;
}
spin_lock_irqsave(&dev->lock, flags);
if (mt_set_pwm_test_sel_hal(val))
goto err;
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
err:
spin_unlock_irqrestore(&dev->lock, flags);
return -EPARMNOSUPPORT;
}
s32 mt_set_pwm_clk(u32 pwm_no, u32 clksrc, u32 div)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
if (div >= CLK_DIV_MAX) {
pr_debug(T "division excesses CLK_DIV_MAX\n");
return -EPARMNOSUPPORT;
}
if ((clksrc & 0x7FFFFFFF) > CLK_BLOCK_BY_1625_OR_32K) {
pr_debug(T "clksrc excesses CLK_BLOCK_BY_1625_OR_32K\n");
return -EPARMNOSUPPORT;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_clk_hal(pwm_no, clksrc, div);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
s32 mt_get_pwm_clk(u32 pwm_no)
{
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
return mt_get_pwm_clk_hal(pwm_no);
}
/******************************************
* Set PWM_CON register data source
* pwm_no: pwm1~pwm7(0~6)
* val: 0 is fifo mode
* 1 is memory mode
*******************************************/
static s32 mt_set_pwm_con_datasrc(u32 pwm_no, u32 val)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "pwm device doesn't exist\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
if (mt_set_pwm_con_datasrc_hal(pwm_no, val))
goto err;
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
err:
spin_unlock_irqrestore(&dev->lock, flags);
return -EPARMNOSUPPORT;
}
/************************************************
* set the PWM_CON register
* pwm_no : pwm1~pwm7 (0~6)
* val: 0 is period mode
* 1 is random mode
*
***************************************************/
static s32 mt_set_pwm_con_mode(u32 pwm_no, u32 val)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
if (mt_set_pwm_con_mode_hal(pwm_no, val))
goto err;
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
err:
spin_unlock_irqrestore(&dev->lock, flags);
return -EPARMNOSUPPORT;
}
/***********************************************
* Set PWM_CON register, idle value bit
* val: 0 means that idle state is not put out.
* 1 means that idle state is put out
*
* IDLE_FALSE: 0
* IDLE_TRUE: 1
***********************************************/
static s32 mt_set_pwm_con_idleval(u32 pwm_no, u16 val)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
if (mt_set_pwm_con_idleval_hal(pwm_no, val))
goto err;
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
err:
spin_unlock_irqrestore(&dev->lock, flags);
return -EPARMNOSUPPORT;
}
/*********************************************
* Set PWM_CON register guardvalue bit
* val: 0 means guard state is not put out.
* 1 mens guard state is put out.
*
* GUARD_FALSE: 0
* GUARD_TRUE: 1
**********************************************/
static s32 mt_set_pwm_con_guardval(u32 pwm_no, u16 val)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
if (mt_set_pwm_con_guardval_hal(pwm_no, val))
goto err;
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
err:
spin_unlock_irqrestore(&dev->lock, flags);
return -EPARMNOSUPPORT;
}
/*************************************************
* Set PWM_CON register stopbits
* stop bits should be less then 0x3f
*
**************************************************/
static s32 mt_set_pwm_con_stpbit(u32 pwm_no, u32 stpbit, u32 srcsel)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
if (srcsel == PWM_FIFO) {
if (stpbit > 0x3f) {
pr_debug(T "stpbit execess in fifo mode\n");
return -EPARMNOSUPPORT;
}
} else if (srcsel == MEMORY) {
if (stpbit > 0x1f) {
pr_debug(T "stpbit excess in memory mode\n");
return -EPARMNOSUPPORT;
}
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_con_stpbit_hal(pwm_no, stpbit, srcsel);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set PWM_CON register oldmode bit
* val: 0 means disable oldmode
* 1 means enable oldmode
*
* OLDMODE_DISABLE: 0
* OLDMODE_ENABLE: 1
******************************************************/
static s32 mt_set_pwm_con_oldmode(u32 pwm_no, u32 val)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
if (mt_set_pwm_con_oldmode_hal(pwm_no, val))
goto err;
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
err:
spin_unlock_irqrestore(&dev->lock, flags);
return -EPARMNOSUPPORT;
}
/***********************************************************
* Set PWM_HIDURATION register
*
*************************************************************/
static s32 mt_set_pwm_HiDur(u32 pwm_no, u16 DurVal)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_HiDur_hal(pwm_no, DurVal);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/************************************************
* Set PWM Low Duration register
*************************************************/
static s32 mt_set_pwm_LowDur(u32 pwm_no, u16 DurVal)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_LowDur_hal(pwm_no, DurVal);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/***************************************************
* Set PWM_GUARDDURATION register
* pwm_no: PWM1~PWM7(0~6)
* DurVal: the value of guard duration
****************************************************/
static s32 mt_set_pwm_GuardDur(u32 pwm_no, u16 DurVal)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_GuardDur_hal(pwm_no, DurVal);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set pwm_buf0_addr register
* pwm_no: pwm1~pwm7 (0~6)
* addr: data address
******************************************************/
s32 mt_set_pwm_buf0_addr(u32 pwm_no, dma_addr_t addr)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_buf0_addr_hal(pwm_no, addr);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set pwm_buf0_size register
* pwm_no: pwm1~pwm7 (0~6)
* size: size of data
******************************************************/
s32 mt_set_pwm_buf0_size(u32 pwm_no, u16 size)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_buf0_size_hal(pwm_no, size);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set pwm_send_data0 register
* pwm_no: pwm1~pwm7 (0~6)
* data: the data in the register
******************************************************/
static s32 mt_set_pwm_send_data0(u32 pwm_no, u32 data)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_send_data0_hal(pwm_no, data);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set pwm_send_data1 register
* pwm_no: pwm1~pwm7 (0~6)
* data: the data in the register
******************************************************/
static s32 mt_set_pwm_send_data1(u32 pwm_no, u32 data)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_send_data1_hal(pwm_no, data);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set pwm_wave_num register
* pwm_no: pwm1~pwm7 (0~6)
* num:the wave number
******************************************************/
static s32 mt_set_pwm_wave_num(u32 pwm_no, u16 num)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_wave_num_hal(pwm_no, num);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set pwm_data_width register.
* This is only for old mode
* pwm_no: pwm1~pwm7 (0~6)
* width: set the guard value in the old mode
******************************************************/
static s32 mt_set_pwm_data_width(u32 pwm_no, u16 width)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_data_width_hal(pwm_no, width);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set pwm_thresh register
* pwm_no: pwm1~pwm7 (0~6)
* thresh: the thresh of the wave
******************************************************/
static s32 mt_set_pwm_thresh(u32 pwm_no, u16 thresh)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T " pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_thresh_hal(pwm_no, thresh);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set pwm_send_wavenum register
* pwm_no: pwm1~pwm7 (0~6)
*
******************************************************/
s32 mt_get_pwm_send_wavenum(u32 pwm_no)
{
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EBADADDR;
}
if (pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excesses PWM_MAX\n");
return -EEXCESSPWMNO;
}
return mt_get_pwm_send_wavenum_hal(pwm_no);
}
/*******************************************
* Set intr enable register
* pwm_intr_enable_bit: the intr bit,
*
*********************************************/
s32 mt_set_intr_enable(u32 pwm_intr_enable_bit)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_intr_enable_bit >= PWM_INT_ENABLE_BITS_MAX) {
pr_debug(T " pwm inter enable bit is not right.\n");
return -EEXCESSBITS;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_intr_enable_hal(pwm_intr_enable_bit);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
/*****************************************************
* Set intr status register
* pwm_no: pwm1~pwm7 (0~6)
* pwm_intr_status_bit
******************************************************/
s32 mt_get_intr_status(u32 pwm_intr_status_bit)
{
unsigned long flags;
int ret;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_intr_status_bit >= PWM_INT_STATUS_BITS_MAX) {
pr_debug(T "status bit excesses PWM_INT_STATUS_BITS_MAX\n");
return -EEXCESSBITS;
}
spin_lock_irqsave(&dev->lock, flags);
ret = mt_get_intr_status_hal(pwm_intr_status_bit);
spin_unlock_irqrestore(&dev->lock, flags);
return ret;
}
/*****************************************************
* Set intr ack register
* pwm_no: pwm1~pwm7 (0~6)
* pwm_intr_ack_bit
******************************************************/
s32 mt_set_intr_ack(u32 pwm_intr_ack_bit)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return -EINVALID;
}
if (pwm_intr_ack_bit >= PWM_INT_ACK_BITS_MAX) {
pr_debug(T "ack bit excesses PWM_INT_ACK_BITS_MAX\n");
return -EEXCESSBITS;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_intr_ack_hal(pwm_intr_ack_bit);
spin_unlock_irqrestore(&dev->lock, flags);
return RSUCCESS;
}
void mt_set_pwm_3dlcm_enable(u8 enable)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_3dlcm_enable_hal(enable);
spin_unlock_irqrestore(&dev->lock, flags);
}
void mt_set_pwm_3dlcm_inv(u32 pwm_no, u8 inv)
{
unsigned long flags;
struct pwm_device *dev = pwm_dev;
if (!dev) {
pr_debug(T "dev is not valid\n");
return;
}
spin_lock_irqsave(&dev->lock, flags);
mt_set_pwm_3dlcm_inv_hal(pwm_no, inv);
spin_unlock_irqrestore(&dev->lock, flags);
}
s32 pwm_set_easy_config(struct pwm_easy_config *conf)
{
u32 duty = 0;
u16 duration = 0;
u32 data_AllH = 0xffffffff;
u32 data0 = 0;
u32 data1 = 0;
if (conf->pwm_no >= PWM_MAX) {
pr_debug(T "pwm number excess PWM_MAX\n");
return -EEXCESSPWMNO;
}
if (conf->clk_div >= CLK_DIV_MAX) {
pr_debug(T "PWM clock division invalid\n");
return -EINVALID;
}
if (conf->clk_src >= PWM_CLK_SRC_INVALID) {
pr_debug(T "PWM clock source invalid\n");
return -EINVALID;
}
if (conf->duty < 0) {
pr_debug(T "duty parameter is invalid\n");
return -EINVALID;
}
pr_debug(T "%s\n", __func__);
if (conf->duty == 0) {
mt_set_pwm_disable(conf->pwm_no);
mt_pwm_power_off(conf->pwm_no, conf->pmic_pad);
return RSUCCESS;
}
duty = conf->duty;
duration = conf->duration;
switch (conf->clk_src) {
case PWM_CLK_OLD_MODE_BLOCK:
case PWM_CLK_OLD_MODE_32K:
if (duration > 8191 || duration < 0) {
pr_debug(T "duration invalid parameter\n");
return -EPARMNOSUPPORT;
}
if (duration < 10)
duration = 10;
break;
case PWM_CLK_NEW_MODE_BLOCK:
case PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625:
if (duration > 65535 || duration < 0) {
pr_debug(T "invalid parameters\n");
return -EPARMNOSUPPORT;
}
break;
default:
pr_debug(T "invalid clock source\n");
return -EPARMNOSUPPORT;
}
if (duty > 100)
duty = 100;
if (duty > 50) {
data0 = data_AllH;
data1 = data_AllH >> ((PWM_NEW_MODE_DUTY_TOTAL_BITS *
(100 - duty))/100);
} else {
data0 = data_AllH >> ((PWM_NEW_MODE_DUTY_TOTAL_BITS *
(50 - duty))/100);
pr_debug(T "DATA0 :0x%x\n", data0);
data1 = 0;
}
mt_pwm_power_on(conf->pwm_no, conf->pmic_pad);
if (conf->pmic_pad)
mt_pwm_sel_pmic(conf->pwm_no);
else
mt_pwm_sel_ap(conf->pwm_no);
mt_set_pwm_con_guardval(conf->pwm_no, GUARD_TRUE);
switch (conf->clk_src) {
case PWM_CLK_OLD_MODE_32K:
mt_set_pwm_con_oldmode(conf->pwm_no, OLDMODE_ENABLE);
mt_set_pwm_clk(conf->pwm_no, CLK_BLOCK_BY_1625_OR_32K,
conf->clk_div);
break;
case PWM_CLK_OLD_MODE_BLOCK:
mt_set_pwm_con_oldmode(conf->pwm_no, OLDMODE_ENABLE);
mt_set_pwm_clk(conf->pwm_no, CLK_BLOCK, conf->clk_div);
break;
case PWM_CLK_NEW_MODE_BLOCK:
mt_set_pwm_con_oldmode(conf->pwm_no, OLDMODE_DISABLE);
mt_set_pwm_clk(conf->pwm_no, CLK_BLOCK, conf->clk_div);
mt_set_pwm_con_datasrc(conf->pwm_no, PWM_FIFO);
mt_set_pwm_con_stpbit(conf->pwm_no, 0x3f, PWM_FIFO);
break;
case PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625:
mt_set_pwm_con_oldmode(conf->pwm_no, OLDMODE_DISABLE);
mt_set_pwm_clk(conf->pwm_no, CLK_BLOCK_BY_1625_OR_32K,
conf->clk_div);
mt_set_pwm_con_datasrc(conf->pwm_no, PWM_FIFO);
mt_set_pwm_con_stpbit(conf->pwm_no, 0x3f, PWM_FIFO);
break;
default:
break;
}
pr_debug(T "The duration is:%x\n", duration);
pr_debug(T "The data0 is:%x\n", data0);
pr_debug(T "The data1 is:%x\n", data1);
mt_set_pwm_HiDur(conf->pwm_no, duration);
mt_set_pwm_LowDur(conf->pwm_no, duration);
mt_set_pwm_GuardDur(conf->pwm_no, 0);
mt_set_pwm_send_data0(conf->pwm_no, data0);
mt_set_pwm_send_data1(conf->pwm_no, data1);
mt_set_pwm_wave_num(conf->pwm_no, 0);
mt_set_pwm_data_width(conf->pwm_no, duration);
mt_set_pwm_thresh(conf->pwm_no, ((duration * conf->duty)/100));
/* For memory barrier */
mb();
mt_set_pwm_enable(conf->pwm_no);
pr_debug(T "mt_set_pwm_enable\n");
return RSUCCESS;
}
EXPORT_SYMBOL(pwm_set_easy_config);
s32 pwm_set_spec_config(struct pwm_spec_config *conf)
{
if (conf->pwm_no >= PWM_MAX) {
pr_debug(T "pwm%d excess PWM_MAX(%d)\n", conf->pwm_no, PWM_MAX);
return -EEXCESSPWMNO;
}
if (conf->mode >= PWM_MODE_INVALID) {
pr_debug(T "PWM mode invalid\n");
return -EINVALID;
}
if (conf->clk_src >= PWM_CLK_SRC_INVALID) {
pr_debug(T "PWM clock source invalid\n");
return -EINVALID;
}
if (conf->clk_div >= CLK_DIV_MAX) {
pr_debug(T "PWM clock division invalid\n");
return -EINVALID;
}
if ((conf->mode == PWM_MODE_OLD &&
(conf->clk_src == PWM_CLK_NEW_MODE_BLOCK))
|| (conf->mode != PWM_MODE_OLD &&
(conf->clk_src == PWM_CLK_OLD_MODE_32K
|| conf->clk_src == PWM_CLK_OLD_MODE_BLOCK))) {
pr_debug(T "parameters match error\n");
return -ERROR;
}
mt_pwm_power_on(conf->pwm_no, conf->pmic_pad);
if (conf->pmic_pad)
mt_pwm_sel_pmic(conf->pwm_no);
switch (conf->mode) {
case PWM_MODE_OLD:
pr_debug(T "PWM_MODE_OLD\n");
mt_set_pwm_con_oldmode(conf->pwm_no, OLDMODE_ENABLE);
mt_set_pwm_con_idleval(conf->pwm_no,
conf->PWM_MODE_OLD_REGS.IDLE_VALUE);
mt_set_pwm_con_guardval(conf->pwm_no,
conf->PWM_MODE_OLD_REGS.GUARD_VALUE);
mt_set_pwm_GuardDur(conf->pwm_no,
conf->PWM_MODE_OLD_REGS.GDURATION);
mt_set_pwm_wave_num(conf->pwm_no,
conf->PWM_MODE_OLD_REGS.WAVE_NUM);
mt_set_pwm_data_width(conf->pwm_no,
conf->PWM_MODE_OLD_REGS.DATA_WIDTH);
mt_set_pwm_thresh(conf->pwm_no,
conf->PWM_MODE_OLD_REGS.THRESH);
pr_debug(T "PWM set old mode finish\n");
break;
case PWM_MODE_FIFO:
pr_debug(T "PWM_MODE_FIFO\n");
mt_set_pwm_con_oldmode(conf->pwm_no, OLDMODE_DISABLE);
mt_set_pwm_con_datasrc(conf->pwm_no, PWM_FIFO);
mt_set_pwm_con_mode(conf->pwm_no, PERIOD);
mt_set_pwm_con_idleval(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.IDLE_VALUE);
mt_set_pwm_con_guardval(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.GUARD_VALUE);
mt_set_pwm_HiDur(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.HDURATION);
mt_set_pwm_LowDur(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.LDURATION);
mt_set_pwm_GuardDur(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.GDURATION);
mt_set_pwm_send_data0(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.SEND_DATA0);
mt_set_pwm_send_data1(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.SEND_DATA1);
mt_set_pwm_wave_num(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.WAVE_NUM);
mt_set_pwm_con_stpbit(conf->pwm_no,
conf->PWM_MODE_FIFO_REGS.STOP_BITPOS_VALUE,
PWM_FIFO);
break;
case PWM_MODE_MEMORY:
pr_debug(T "PWM_MODE_MEMORY\n");
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(conf->pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(1);
#endif
mt_set_pwm_con_oldmode(conf->pwm_no, OLDMODE_DISABLE);
mt_set_pwm_con_datasrc(conf->pwm_no, MEMORY);
mt_set_pwm_con_mode(conf->pwm_no, PERIOD);
mt_set_pwm_con_idleval(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.IDLE_VALUE);
mt_set_pwm_con_guardval(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.GUARD_VALUE);
mt_set_pwm_HiDur(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.HDURATION);
mt_set_pwm_LowDur(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.LDURATION);
mt_set_pwm_GuardDur(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.GDURATION);
mt_set_pwm_buf0_addr(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.BUF0_BASE_ADDR);
mt_set_pwm_buf0_size(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.BUF0_SIZE);
mt_set_pwm_wave_num(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.WAVE_NUM);
mt_set_pwm_con_stpbit(conf->pwm_no,
conf->PWM_MODE_MEMORY_REGS.STOP_BITPOS_VALUE,
MEMORY);
break;
default:
break;
}
switch (conf->clk_src) {
case PWM_CLK_OLD_MODE_BLOCK:
mt_set_pwm_clk(conf->pwm_no, CLK_BLOCK, conf->clk_div);
pr_debug(T "Enable oldmode and set clock block\n");
break;
case PWM_CLK_OLD_MODE_32K:
mt_set_pwm_clk(conf->pwm_no,
0x80000000 | CLK_BLOCK_BY_1625_OR_32K, conf->clk_div);
pr_debug(T "Enable oldmode and set clock 32K\n");
break;
case PWM_CLK_NEW_MODE_BLOCK:
mt_set_pwm_clk(conf->pwm_no, CLK_BLOCK, conf->clk_div);
pr_debug(T "Enable newmode and set clock block\n");
break;
case PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625:
mt_set_pwm_clk(conf->pwm_no, CLK_BLOCK_BY_1625_OR_32K,
conf->clk_div);
pr_debug(T "Enable newmode and set clock 32K\n");
break;
default:
break;
}
/* For memory barrier */
mb();
mt_set_pwm_enable(conf->pwm_no);
pr_debug(T "mt_set_pwm_enable\n");
return RSUCCESS;
}
EXPORT_SYMBOL(pwm_set_spec_config);
void mt_pwm_dump_regs(void)
{
mt_pwm_dump_regs_hal();
pr_debug(T "power_flag: 0x%x\n", (unsigned int)pwm_dev->power_flag);
}
EXPORT_SYMBOL(mt_pwm_dump_regs);
struct platform_device pwm_plat_dev = {
.name = "mt-pwm",
};
#if PWM_LDVT_FLAG
static int pwm_gpio_config(struct device *dev, int pwm_no)
{
int ret = 0;
struct pinctrl *pwm_pinctrl;
struct pinctrl_state *pwm_pins_default;
struct pinctrl_state *pwm_pins_conf[3];
pr_debug(T "set pwm[%d] gpio:%s\n", pwm_no, dev_name(dev));
pwm_pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(pwm_pinctrl)) {
ret = PTR_ERR(pwm_pinctrl);
pr_debug(T "pinctrl get failed!!\n");
return ret;
}
pwm_pins_default = pinctrl_lookup_state(pwm_pinctrl, "default");
if (IS_ERR(pwm_pins_default)) {
ret = PTR_ERR(pwm_pins_default);
pr_debug("find pinctrl default fail\n");
}
if (pwm_no == 0) {
pwm_pins_conf[0] =
pinctrl_lookup_state(pwm_pinctrl, "pwm0_pins");
if (IS_ERR(pwm_pins_conf[0])) {
ret = PTR_ERR(pwm_pins_conf[0]);
pr_debug(T "Cannot find pinctrl pwm0!\n");
return ret;
}
pr_debug(T "PWM0 state find OK\n");
pinctrl_select_state(pwm_pinctrl, pwm_pins_conf[0]);
} else if (pwm_no == 1) {
pwm_pins_conf[1] =
pinctrl_lookup_state(pwm_pinctrl, "pwm1_pins");
if (IS_ERR(pwm_pins_conf[1])) {
ret = PTR_ERR(pwm_pins_conf[1]);
pr_debug(T "Cannot find pinctrl pwm1!\n");
return ret;
}
pr_debug(T "PWM1 state find OK\n");
pinctrl_select_state(pwm_pinctrl, pwm_pins_conf[1]);
} else if (pwm_no == 2) {
pwm_pins_conf[2] =
pinctrl_lookup_state(pwm_pinctrl, "pwm2_pins");
if (IS_ERR(pwm_pins_conf[2])) {
ret = PTR_ERR(pwm_pins_conf[2]);
pr_debug(T "Cannot find pinctrl pwm2!\n");
return ret;
}
pr_debug(T "PWM2 state find OK\n");
pinctrl_select_state(pwm_pinctrl, pwm_pins_conf[2]);
} else {
pr_debug(T "Invalid PWM Number!\n");
return 1;
}
return ret;
}
#endif
#if PWM_LDVT_FLAG/* PWM LDVT Hight Test Case */
#define PWM_SCLK_SEL 1/* sub CLK 26M select */
#define PWM_BCLK_SEL 0/* bus CLK(maybe 64M or 66M) select */
#define LARGE_8G_DRAM_TEST 0/* default not en 8G */
#endif
static ssize_t pwm_debug_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
#if PWM_LDVT_FLAG
int ret = 0;
int cmd = 0;
int sub_cmd = 0;
int pwm_no = 0;
pr_debug(T "power_flag: 0x%x\n", (unsigned int)pwm_dev->power_flag);
ret = sscanf(buf, "%d,%d,%d", &pwm_no, &cmd, &sub_cmd);
if (!ret) {
pr_debug("%s param get failed\n", __func__);
return count;
}
pr_debug(T "pwm[%d]--cmd: %d.%d\n", pwm_no, cmd, sub_cmd);
/* set gpio mode */
if (cmd) {
if (pwm_no < PWM_NUM)
ret = pwm_gpio_config(dev, pwm_no);
else {
pr_debug("pwm: No such pwm[%d]\n", pwm_no);
return count;
}
}
if (cmd == 0) {
if (sub_cmd == 0) {/* dump RG */
if (test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_dump_regs();
} else if (sub_cmd == 1) {/* disable pwm */
if (test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_disable(pwm_no, false);
pr_debug(T "[PWM%d] poweroff\n", pwm_no);
} else if (sub_cmd == 2) {/* get pwm clk */
if (test_bit(pwm_no, &(pwm_dev->power_flag)))
pr_debug(T "[PWM%d] get current clk:%d\n",
pwm_no, mt_get_pwm_clk(pwm_no));
} else
pr_debug(T "[PWM%d] Invalid cmd:%d\n", pwm_no, sub_cmd);
} else if (cmd == 1) {
if (sub_cmd == 1) {/* 26M/66M/32K test */
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST:OLD CLK SOURCE 26M\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_OLD_MODE_BLOCK;
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err! %d\n",
pwm_no, ret);
} else if (sub_cmd == 2) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST:OLD CLK SOURCE 66M\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_OLD_MODE_BLOCK;
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_SEL_TOPCKGEN);
#else
mt_pwm_26M_clk_enable_hal(PWM_BCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!%d\n",
pwm_no, ret);
} else if (sub_cmd == 3) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST:OLD CLK SOURCE 66M\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_OLD_MODE_BLOCK;
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_32K);
#else
mt_pwm_26M_clk_enable_hal(1);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!%d\n",
pwm_no, ret);
} else {
pr_debug(T "[PWM%d] TEST: Invalid sub_cmd:%d\n",
pwm_no, sub_cmd);
} /* end sub cmd */
} else if (cmd == 2) {
if (sub_cmd == 1) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST: FIFO STOP BIT 63\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_FIFO;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625;
conf.PWM_MODE_FIFO_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_FIFO_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_FIFO_REGS.STOP_BITPOS_VALUE = 63;
conf.PWM_MODE_FIFO_REGS.HDURATION = 0;
conf.PWM_MODE_FIFO_REGS.LDURATION = 0;
conf.PWM_MODE_FIFO_REGS.GDURATION = 0;
conf.PWM_MODE_FIFO_REGS.SEND_DATA0 = 0x0000ff11;
conf.PWM_MODE_FIFO_REGS.SEND_DATA1 = 0xffffffff;
conf.PWM_MODE_FIFO_REGS.WAVE_NUM = 0;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!%d\n",
pwm_no, ret);
} else if (sub_cmd == 2) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST: FIFO STOP BIT 62\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_FIFO;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625;
conf.PWM_MODE_FIFO_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_FIFO_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_FIFO_REGS.STOP_BITPOS_VALUE = 62;
conf.PWM_MODE_FIFO_REGS.HDURATION = 0;
conf.PWM_MODE_FIFO_REGS.LDURATION = 0;
conf.PWM_MODE_FIFO_REGS.GDURATION = 0;
conf.PWM_MODE_FIFO_REGS.SEND_DATA0 = 0x0000ff11;
conf.PWM_MODE_FIFO_REGS.SEND_DATA1 = 0xffffffff;
conf.PWM_MODE_FIFO_REGS.WAVE_NUM = 0;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!%d\n",
pwm_no, ret);
} else if (sub_cmd == 3) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST: FIFO STOP BIT 31\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_FIFO;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625;
conf.PWM_MODE_FIFO_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_FIFO_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_FIFO_REGS.STOP_BITPOS_VALUE = 31;
conf.PWM_MODE_FIFO_REGS.HDURATION = 0;
conf.PWM_MODE_FIFO_REGS.LDURATION = 0;
conf.PWM_MODE_FIFO_REGS.GDURATION = 0;
conf.PWM_MODE_FIFO_REGS.SEND_DATA0 = 0x0000ff11;
conf.PWM_MODE_FIFO_REGS.SEND_DATA1 = 0xffffffff;
conf.PWM_MODE_FIFO_REGS.WAVE_NUM = 0;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!%d\n",
pwm_no, ret);
} else
pr_debug(T "[PWM%d] TEST: Invalid sub_cmd:%d\n",
pwm_no, sub_cmd);
} else if (cmd == 3) {
if (sub_cmd == 1) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] OLD CLK 32KHZ/WAVE\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_OLD_MODE_32K; /* 32KHz */
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;/* duty:50% */
conf.PWM_MODE_OLD_REGS.THRESH = 4;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!%d\n",
pwm_no, ret);
} else if (sub_cmd == 2) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST:OLD CLK 32KHZ/WAVE\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_OLD_MODE_32K; /* 32KHz */
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 1;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;/* duty:50% */
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!ret:%d\n",
pwm_no, ret);
} else if (sub_cmd == 3) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] OLD CLK 32KHZ/WAVE\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_OLD_MODE_32K; /* 32KHz */
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 10;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;/* duty:50% */
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d]CONFIG err%d\n",
pwm_no, ret);
} else if (sub_cmd == 4) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d]OLD CLK 16KHZ/WAVE\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV2;
/* 16K */
conf.clk_src = PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625;
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!ret:%d\n",
pwm_no, ret);
} else
pr_debug(T "[PWM%d] TEST: Invalid sub_cmd:%d ===>\n",
pwm_no, sub_cmd);
} else if (cmd == 4) {
if (sub_cmd == 1) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST: OLD CLK 26MHZ\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_OLD_MODE_BLOCK;
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err!ret:%d\n",
pwm_no, ret);
} else if (sub_cmd == 2) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] TEST: OLD CLK DIV 26MHz/1625\n",
pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625;
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err:%d\n",
pwm_no, ret);
} else if (sub_cmd == 3) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d]OLD CLK DIV 26MHz/16/13:125KHZ\n",
pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV16;
conf.clk_src = PWM_CLK_OLD_MODE_BLOCK;
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 12;
conf.PWM_MODE_OLD_REGS.THRESH = 6;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_26M);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err:%d\n",
pwm_no, ret);
} else {
pr_debug(T "[PWM%d] TEST: Invalid sub_cmd:%d\n",
pwm_no, sub_cmd);
}
} else if (cmd == 5) {
if (sub_cmd == 1) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d]OLD Finish interrupt\n", pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_OLD;
conf.clk_div = CLK_DIV1;
/* 32K */
conf.clk_src = PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625;
conf.PWM_MODE_OLD_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_OLD_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_OLD_REGS.GDURATION = 0;
conf.PWM_MODE_OLD_REGS.WAVE_NUM = 10;
conf.PWM_MODE_OLD_REGS.DATA_WIDTH = 9;
conf.PWM_MODE_OLD_REGS.THRESH = 4;
intr_pwm_nu[pwm_no]++;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
mt_set_intr_enable(PWM1_INT_FINISH_EN+2*pwm_no);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_SEL_TOPCKGEN);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err:%d\n",
pwm_no, ret);
} else if (sub_cmd == 2) {
struct pwm_spec_config conf;
pr_debug(T "[PWM%d] FIFO Finish interrupt sig-pwm\n",
pwm_no);
conf.pwm_no = pwm_no;
conf.mode = PWM_MODE_FIFO;
conf.clk_div = CLK_DIV1;
conf.clk_src = PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625;
conf.PWM_MODE_FIFO_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_FIFO_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_FIFO_REGS.STOP_BITPOS_VALUE = 63;
conf.PWM_MODE_FIFO_REGS.HDURATION = 0;
conf.PWM_MODE_FIFO_REGS.LDURATION = 0;
conf.PWM_MODE_FIFO_REGS.GDURATION = 0;
conf.PWM_MODE_FIFO_REGS.SEND_DATA0 = 0x0000ff11;
conf.PWM_MODE_FIFO_REGS.SEND_DATA1 = 0xffffffff;
conf.PWM_MODE_FIFO_REGS.WAVE_NUM = 10;
intr_pwm_nu[pwm_no]++;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_SEL_TOPCKGEN);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
mt_set_intr_enable(PWM1_INT_FINISH_EN+2*pwm_no);
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST: CONFIG err:%d\n",
pwm_no, ret);
} else if (sub_cmd == 3) {
int t_nu = 0;
struct pwm_spec_config conf[PWM_MAX];
pr_debug(T "[PWM%d] FIFO Finish interrupt multi-pwm\n",
pwm_no);
for (t_nu = 0; t_nu <= pwm_no; t_nu++) {
conf[t_nu].pwm_no = pwm_no;
conf[t_nu].mode = PWM_MODE_FIFO;
conf[t_nu].clk_div = CLK_DIV2;
conf[t_nu].clk_src = PWM_CLK_NEW_MODE_BLOCK;
conf[t_nu].PWM_MODE_FIFO_REGS.IDLE_VALUE =
IDLE_FALSE;
conf[t_nu].PWM_MODE_FIFO_REGS.GUARD_VALUE =
GUARD_FALSE;
conf[t_nu].PWM_MODE_FIFO_REGS.STOP_BITPOS_VALUE = 31;
conf[t_nu].PWM_MODE_FIFO_REGS.HDURATION = 0;
conf[t_nu].PWM_MODE_FIFO_REGS.LDURATION = 0;
conf[t_nu].PWM_MODE_FIFO_REGS.GDURATION = 0;
conf[t_nu].PWM_MODE_FIFO_REGS.SEND_DATA0 =
0x0000ff11;
conf[t_nu].PWM_MODE_FIFO_REGS.SEND_DATA1 =
0xff00ffff;
conf[t_nu].PWM_MODE_FIFO_REGS.WAVE_NUM = 0;
intr_pwm_nu[t_nu]++;
}
for (t_nu = 0; t_nu <= pwm_no; t_nu++) {
if (!test_bit(t_nu, &(pwm_dev->power_flag)))
mt_pwm_power_on(t_nu, 0);
mt_set_intr_enable(PWM1_INT_FINISH_EN+2*t_nu);
#ifdef PWM_HW_V_1_0
mt_pwm_clk_sel_hal(pwm_no, CLK_SEL_TOPCKGEN);
#else
mt_pwm_26M_clk_enable_hal(PWM_SCLK_SEL);
#endif
ret = pwm_set_spec_config(&conf[t_nu]);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d]CONFIG err:%d\n",
t_nu, ret);
}
} else {
pr_debug(T "[PWM%d] TEST: Invalid sub_cmd:%d ===>\n",
pwm_no, sub_cmd);
} /* end sub cmd */
} else if (cmd == 8) {
pr_debug(T "[PWM%d] TEST: 3DLCM test: not implement===>\n",
pwm_no);
} else if (cmd == 9) {
int i = 0;
struct pwm_spec_config conf;
#define PWM_MEM_DMA_SIZE 256
#if LARGE_8G_DRAM_TEST
#define PWM_DMA_TYPE unsigned long long
/* dma_addr_t phys; */
PWM_DMA_TYPE phys;
PWM_DMA_TYPE *virt = NULL;
PWM_DMA_TYPE *membuff = NULL;
#else/* 4G address */
#define PWM_DMA_TYPE unsigned int
/* dma_addr_t phys; */
PWM_DMA_TYPE phys;
PWM_DMA_TYPE *virt = NULL;
PWM_DMA_TYPE *membuff = NULL;
#endif
pr_debug(T "[PWM%d] TEST: MEMO/DMA ===>\n", pwm_no);
conf.mode = PWM_MODE_MEMORY;
conf.pwm_no = pwm_no;
conf.clk_div = CLK_DIV8;
conf.clk_src = PWM_CLK_NEW_MODE_BLOCK;
conf.PWM_MODE_MEMORY_REGS.IDLE_VALUE = IDLE_FALSE;
conf.PWM_MODE_MEMORY_REGS.GUARD_VALUE = GUARD_FALSE;
conf.PWM_MODE_MEMORY_REGS.HDURATION = 119;
conf.PWM_MODE_MEMORY_REGS.LDURATION = 119;
conf.PWM_MODE_MEMORY_REGS.GDURATION = 0;
conf.PWM_MODE_MEMORY_REGS.WAVE_NUM = 0;
conf.PWM_MODE_MEMORY_REGS.STOP_BITPOS_VALUE = 30;
#if LARGE_8G_DRAM_TEST
if (dma_set_coherent_mask(dev, DMA_BIT_MASK(36))) {
pr_debug(T "[PWM] dma alloc fail, dma_mask:0x%llx",
DMA_BIT_MASK(36));
return count;
}
pr_debug(T "[PWM]set dma_mask:0x%llx ", DMA_BIT_MASK(36));
#endif
virt = (PWM_DMA_TYPE *)dma_alloc_coherent(dev,
PWM_MEM_DMA_SIZE, (dma_addr_t *)&phys, GFP_KERNEL);
if (virt == NULL) {
pr_debug(T "[PWM] err:DMA get addr failed!\n");
return count;
}
#if LARGE_8G_DRAM_TEST
pr_debug(T "[PWM] DMA get virt_addr:0x%p, phys_addr:0x%llx\n",
virt, phys);
#else
pr_debug(T "[PWM] DMA get virt_addr:0x%p, phys_addr:0x%x\n",
virt, phys);
#endif
membuff = virt;
for (i = 0; i < (PWM_MEM_DMA_SIZE/(sizeof(PWM_DMA_TYPE)));
i += (sizeof(PWM_DMA_TYPE))) {
membuff[i] = 0xaaaaaaaa;
membuff[i+1] = 0xffff0000;
}
conf.PWM_MODE_MEMORY_REGS.BUF0_SIZE = PWM_MEM_DMA_SIZE;
conf.PWM_MODE_MEMORY_REGS.BUF0_BASE_ADDR = phys;
if (!test_bit(pwm_no, &(pwm_dev->power_flag)))
mt_pwm_power_on(pwm_no, 0);
ret = pwm_set_spec_config(&conf);
if (ret != RSUCCESS)
pr_debug(T "[PWM%d] TEST:CONFIG err:%d\n", pwm_no, ret);
} else {
pr_debug(T "[PWM%d] TEST: Invalid cmd:%d\n", pwm_no, cmd);
}
#endif/* end LDVT flag */
return count;
}
static ssize_t pwm_debug_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
pwm_debug_show_hal();
return sprintf(buf, "\n");
}
static DEVICE_ATTR(pwm_debug, 0644, pwm_debug_show, pwm_debug_store);
static irqreturn_t mt_pwm_irq(int irq, void *intr_pwm_nu)
{
u32 i = 0;
u32 sts = 0;
#if PWM_LDVT_FLAG
u8 *pwm_flag = (u8 *)intr_pwm_nu;
for (i = 0; i < PWM_MAX; i++) {
if (!pwm_flag[i])
continue;
sts = mt_get_intr_status(PWM1_INT_FINISH_EN + (2 * i));
if (sts) {
mt_set_intr_ack(PWM1_INT_FINISH_ACK + (2 * i));
pwm_flag[i]--;
}
pr_debug(T "PWM%d Finished intr come:0x%x\n", i, sts);
sts = mt_get_intr_status(PWM1_INT_UNDERFLOW_EN + (2 * i));
if (sts) {
/* clear interrupt */
mt_set_intr_ack(PWM1_INT_UNDERFLOW_ACK + (2 * i));
pwm_flag[i]--;
}
pr_debug(T "PWM%d underflow intr come:0x%x\n", i, pwm_flag[i]);
}
#else
for (i = 0; i < PWM_MAX*2; i++) {
sts = mt_get_intr_status(i);
if (sts) {
mt_set_intr_ack(i);
pr_info(T "PWM int!!ch=%x\n", i/2);
break;
}
}
#endif
return IRQ_HANDLED;
}
static int mt_pwm_probe(struct platform_device *pdev)
{
int ret, pwm_irqnr;
mt_pwm_platform_init();
pwm_base = of_iomap(pdev->dev.of_node, 0);
if (!pwm_base) {
pr_err(T "PWM iomap failed\n");
return -ENODEV;
}
ret = mt_get_pwm_clk_src(pdev);
if (ret != 0)
pr_err(T "[%s]: clk get Fail :%d\n", __func__, ret);
platform_set_drvdata(pdev, pwm_dev);
ret = device_create_file(&pdev->dev, &dev_attr_pwm_debug);
if (ret)
pr_debug(T "[pwm]error creating sysfs files: pwm_debug\n");
pwm_irqnr = irq_of_parse_and_map(pdev->dev.of_node, 0);
if (!pwm_irqnr) {
pr_debug(T "PWM get irqnr failed\n");
return -ENODEV;
}
pr_debug(T "pwm base: 0x%p pwm irq: %d\n",
pwm_base, pwm_irqnr);
pwm_irqnr = platform_get_irq(pdev, 0);
if (pwm_irqnr <= 0) {
pr_err("[pwm]get irq failed!\n");
return -EINVAL;
}
#if PWM_LDVT_FLAG
ret = devm_request_irq(&pdev->dev, pwm_irqnr, mt_pwm_irq,
IRQF_TRIGGER_NONE, PWM_DEVICE, (void *) intr_pwm_nu);
#else
ret = devm_request_irq(&pdev->dev, pwm_irqnr, mt_pwm_irq,
IRQF_TRIGGER_NONE, PWM_DEVICE, NULL);
#endif
if (ret < 0) {
pr_err(T "[PWM]Request IRQ %d failed-------\n", pwm_irqnr);
return ret;
}
mutex_init(&pwm_power_lock);
pr_debug(T "pwm probe Done!!\n");
return RSUCCESS;
}
static int mt_pwm_remove(struct platform_device *pdev)
{
if (!pdev) {
pr_debug(T "The plaform device is not exist\n");
return -EBADADDR;
}
device_remove_file(&pdev->dev, &dev_attr_pwm_debug);
pr_debug(T "%s\n", __func__);
return RSUCCESS;
}
static void mt_pwm_shutdown(struct platform_device *pdev)
{
pr_debug(T "%s\n", __func__);
}
static const struct of_device_id pwm_of_match[] = {
{.compatible = "mediatek,pwm",},
{},
};
struct platform_driver pwm_plat_driver = {
.probe = mt_pwm_probe,
.remove = mt_pwm_remove,
.shutdown = mt_pwm_shutdown,
.driver = {
.name = "mt-pwm",
.of_match_table = pwm_of_match,
},
};
static int __init mt_pwm_init(void)
{
int ret;
ret = platform_driver_register(&pwm_plat_driver);
if (ret < 0) {
pr_err(T "platform_driver_register error\n");
goto out;
}
out:
mt_pwm_init_power_flag(&(pwm_dev->power_flag));
return ret;
}
static void __exit mt_pwm_exit(void)
{
platform_driver_unregister(&pwm_plat_driver);
}
module_init(mt_pwm_init);
module_exit(mt_pwm_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MTK");
MODULE_DESCRIPTION(" This module is used for chip of mediatek");