日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mt6577驱动开发 笔记版 转载请注明出处---crosskernel@gmail.com

發布時間:2023/12/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mt6577驱动开发 笔记版 转载请注明出处---crosskernel@gmail.com 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.




3 Preloader & Uboot

3.1 Preloader




3.1.1Preloader結構
Preloader的主題結構在文件:“alps\mediatek\platform\mt6577\preloader\src\core\main.c”中。


void main(void)
{
//時鐘、uart、mcp等初始化
bldr_pre_process();

bldr_handshake(&handler);

//這里加載DSP 3G AP的ROM。

#if CFG_LOAD_UBOOT
addr = CFG_UBOOT_MEMADDR;
//加載uboot
? ? if (bldr_load_part(PART_UBOOT, bootdev, &addr) != 0)
? ? ? ? goto error;
#endif



//跳轉到uboot
bldr_jump(addr, BOOT_ARGUMENT_ADDR, sizeof(boot_arg_t));

}


3.1.2 PLL與Clock
PLL介紹在datasheet 1190
Pll.c中“void mt6577_pll_init(void)”
似乎PLL主要是在preloader里打開的。




//設置的PLL
void mt6577_pll_init(void)
{


}


//根據MCP的型號設置DDR相關時鐘
int mt6577_pll_init2 (void)
{
if (mt6577_get_dram_type() == 2)
? ? {
? ? ? ?…
? ? }
? ? else if (mt6577_get_dram_type() == 3)
{

? ? }
}




3.1.3 DDR的初始化


EMI_SETTINGS emi_settings[]里面定義了KMNJS000ZM_B205 H9TP32A4GDMCPR KMSJS000KM_B308等類型的MCP的配置參數。


在“void mt6577_set_emi (void)”里面會根據“emi_settings[]”的配置初始化MCP控制器。




3.1.4 鏡像布局與加載


鏡像布局參數被存放在文件:
mediatek/custom/out/mt6577preloader/cust_part.c里
static part_t platform_parts[PART_MAX_COUNT];里面記錄每個鏡像的長度。






在mediatek/platform/mt6577/preloader/src/core/part.c里
函數int part_init(void)里,依次累加前面所有鏡像,算出當前鏡像的起始位置。


3.1.5 EMMC 驅動


#define MMC_HOST_ID ?0


u32 mmc_init_device(void)
{…
//emmc 零通道
ret = mmc_init(MMC_HOST_ID);

}


//分別初始化host和card
int mmc_init(int id)
{ ??
? ? …


? ? host = &sd_host[id];
? ? card = &sd_card[id];
? ? err = mmc_init_host(host, id);
? ? if (err == MMC_ERR_NONE)
? ? ? ? err = mmc_init_card(host, card);

}


//host初始化
int mmc_init_host(struct mmc_host *host, int id)
{
? ? memset(host, 0, sizeof(struct mmc_host));


? ? return msdc_init(host, id);
}


/*
#define MSDC0_BASE ? ? ? ? ?(IO_PHYS + 0x01220000)
#define MSDC1_BASE ? ? ? ? ?(IO_PHYS + 0x01230000)
#define MSDC2_BASE ? ? ? ? ?(IO_PHYS + 0x01250000)
#define MSDC3_BASE ? ? ? ? ?(IO_PHYS + 0x01240000)


#define IO_PHYS ? ? ? ? ? ? 0xC0000000


對于通道0,基地址在MSDC0_BASE即為0xC1220000。其余通道基地址在0xC1230000 0xC1240000 ?0xC1250000,但是datasheet里只有0通道0xC1220000的信息。


*/




int msdc_init(struct mmc_host *host, int id)
{
u32 baddr[] = {MSDC0_BASE, MSDC1_BASE, MSDC2_BASE, MSDC3_BASE};
//基地址選擇0通道
? ? u32 base = baddr[id];


? ? //0通道
host->id ? ? = id;
//基地址
? ? host->base ? = base;
host->f_max ?= MSDC_MAX_SCLK;

//以下所有對0通道的寄存器操作都是基于這基地址“base”進行的


}


3.3 uboot
Uboot代碼:


Generic部分:
Uboot的generic的部分位于“bootable/bootloader/uboot/”


Mt6577相關部分相關位于:
mediatek/platform/mt6577/uboot/
mediatek/custom/out/mt6577/uboot/






uboot的config:
“alps\mediatek\custom\out\mt6577\uboot\inc\configs\ubconfigs.h”
3.3.1 uboot初始化流程
Uboot初始化主體位于“bootable/bootloader/uboot/arch/arm/lib/board.c”


void start_armboot (void)
{

//執行初始化例程數組
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)?
{
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}

//執行平臺相關misc初始化
#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r ();
#endif


}


在“bootable/bootloader/uboot/arch/arm/lib/board.c”定義了初始化例程指針數組,其中的各項例程不同的板卡有自己不同的實現:


init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
dram_init, ? ? ? ? ? ? ?/* configure available RAM banks */ /* ?change the original init order */
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
? ? …
display_dram_config,
NULL,
};






Mt6577的初始化例程的實現位于“mediatek/platform/mt6577/uboot/mt6577_board.c”:


int board_init (void)
{…
mtk_serial_init();

mt6577_pinmux_init();s

pmic6329_init();




}




3.3.2 鏡像布局與分區


Uboot在“int misc_init_r (…)”里對鏡像分區初始化




int misc_init_r (void)
{…
mt6577_part_init(BLK_NUM(16 * GB));

}


/**********************************************************************/


在“mediatek/custom/out/mt6577/uboot/partition.h”里對分區表定義如下:


#include <common.h>
/*該文件可能就是:
“mediatek/custom/out/mt6577/uboot/inc/mt65xx_partition.h”
*/
#include "mt65xx_partition.h"


part_t partition_layout[] = {
{PART_PRELOADER, PART_BLKS_PRELOADER, PART_FLAG_NONE,0},
{PART_DSP_DL, PART_BLKS_DSP_DL, 0, PART_FLAG_NONE},

};




3.3.3 gpio初始化
DCT工具產生的“cust_gpio_boot.h”被如下文件:
mediatek/platform/mt6577/uboot/mt6577_gpio_init.c?




默認設置的定義:


u16 gpio_init_mode_data[];
u16 gpio_init_dir_data[];
u16 gpio_init_pullen_data[];



設置默認設置
void mt_gpio_set_default(void)






4 Kernel
內核源碼


標準內核:
Alps/kernel


Mtk部分內核
? Alps/mediatek/source/kernel/
? Alps/mediatek/platform/mt6577/kernel
? Alps/mediatek/custom/*/kernel下面也有,如
Alps/mediatek/custom/common/kernel
Alps/mediatek/custom/mt6577/kernel




4.1 ARCH初始化


4.1.1 Board支持
在“alps/mediatek/platform/mt6577/kernel/core/core.c”定義


MACHINE_START(MT6577, "MT6577")
? ? .boot_params ? ?= PHYS_OFFSET + 0x00000100,
? ? .map_io ? ? ? ? = mt6577_map_io,
? ? .init_irq ? ? ? = mt_init_irq,
? ? .timer ? ? ? ? ?= &mt6577_timer,
? ? .init_machine ? = mt6577_init,
? ? .fixup ? ? ? ? ?= mt6577_fixup
MACHINE_END


在“alps/mediatek/platform/mt6577/kernel/core/mt6577_devs.c”注冊device
__init int mt6577_board_init(void)
{

retval = platform_device_register(&mt_hid_dev);
retval = platform_device_register(&mt_device_i2c[i]);
retval = platform_device_register(&AudDrv_device);
retval = platform_device_register(&mt6577_device_fb);
retval = platform_device_register(&mtk_hdmi_dev);
retval = platform_device_register(&mt6577_TVOUT_dev);

}




在“alps/kernel/mediatek/Makefile”里引用“../../mediatek/build/kernel/Makefile”,該文件即為:“alps/mediatek/build/kernel/Makefile”里面定義了相關的mt6577的內核文件:


machine-y ? ? ? := $(call lc,$(MTK_PLATFORM))
ifeq ($(strip $(KBUILD_OUTPUT_SUPPORT)),yes)
MACHINE ? ? ? ? ?:= mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/core/
machdirs ? ? ? ? := mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/core/
else
MACHINE ? ? ? ? := $(MTK_PATH_PLATFORM)/core/
machdirs ? ? ? ?:= $(MTK_PATH_PLATFORM)/core/
endif
platdirs ? ? ? ?:=


ifeq ($(strip $(KBUILD_OUTPUT_SUPPORT)),yes)
drivers-y ? ? ? += mediatek/source/kernel/
drivers-y ? ? ? += mediatek/custom/out/$(FULL_PROJECT)/kernel/
drivers-y ? ? ? += mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/
else
drivers-y ? ? ? += $(MTK_PATH_PLATFORM)/drivers/
drivers-y ? ? ? += $(MTK_PATH_SOURCE)/
drivers-y ? ? ? += $(MTK_PATH_CUSTOM)/
endif






4.1.2 PLL與Clock


mt6577_clock_manager.c中“static void mt6577_clock_init(void)”“static void mt6577_pll_init(void)”


mt6577的clock定義如下
enum mt65xx_clock_id {
? ? /* PERI_GLOBALCON_PDN0 */
? ? MT65XX_PDN_PERI_NFI ? ? ? ? ? ? ? ? = 0,
? ? …
? ??
? ? /* PERI_GLOBALCON_PDN1 */
? ? MT65XX_PDN_PERI_SEJ ? ? ? ? ? ? ? ? = 32,
? ? …
? ? /* MMSYS1 Clock Gating #0 */
MT65XX_PDN_MM_VBUF ? ? ? ? ? ? ? ? ?= 64,

? ? /* MMSYS1 Clock Gating #1 */
? ? MT65XX_PDN_MM_VRZ1 ? ? ? ? ? ? ? ? ?= 96,
? ? …


? ? /*MMSYS1 Clock Gating #2 */
? ? MT65XX_PDN_MM_SCAM ? ? ? ? ? ? ? ? ?= 128,
? ? …
? ??
MT65XX_CLOCK_AUDIO_PDN, /* 32*6 = 192*/
? ? MT65XX_AUDIO_PDN_END ? ? ? ? ? ? ? ?= MT65XX_PDN_AUDIO_I2S,


? ? MT65XX_CLOCK_COUNT,
};


按照32,分組,enbale某個clock時,首先找到分組,然后找到組內偏移,針對某個組進行操作。中間根據clock組編號區分出 AP AP1 MM1 MM2等不同始終組,進行特殊操作。


不同的驅動在自己初始化函數里enable自己需要clock id—實際上enable對應的clock組。


int enable_clock(enum mt65xx_clock_id id, char *mod_name)
{
? ? unsigned long flags;
? ? int ret = 0;
? ? int category = id / CLK_REG_WIDTH;
int offset = id % CLK_REG_WIDTH;




if (CATEGORY_AP1(category)) {

}

if (CATEGORY_MM(category)) {

}
if (CATEGORY_AUD(category)) {

}


ret = enable_clock_internal(category, mask);






5 CpuFreq


5.1 初始化


在“static int mtk_cpufreq_init(…)”里根據處理器的版本選擇調頻表:


static struct mtk_cpu_freq_info mt6575_freqs_e1[] = {
? ? OP(DVFS_F2_MT6575_E1),
? ? OP(DVFS_F1_MT6575_E1),
};


/***************************
* MT6575 E2 DVFS Table
****************************/
static struct mtk_cpu_freq_info mt6575_freqs_e2[] = {
? ? OP(DVFS_F4_MT6575_E2),
? ? …
};


/***************************
* MT6577 E1 DVFS Table
****************************/
static struct mtk_cpu_freq_info mt6577_freqs_e1[] = {
? ? OP(DVFS_F6_MT6577_E1),
? ? …
? ? OP(DVFS_F1_MT6577_E1),
};


/***************************
* MT6577 E1 TM DVFS Table
****************************/
static struct mtk_cpu_freq_info mt6577_freqs_e1_tm[] = {
? ? OP(DVFS_F6_MT6577_E1_TM),
? ? …
? ? OP(DVFS_F1_MT6577_E1_TM),
};






調頻操作在“static int mtk_cpufreq_target()”里完成。




5.2 基本數據結構


調頻例程


static struct cpufreq_driver mtk_cpufreq_driver = {
? ? .verify = mtk_cpufreq_verify,
? ? .target = mtk_cpufreq_target,
? ? .init ? = mtk_cpufreq_init,
? ? .get ? ?= mtk_cpufreq_get,
? ? .name ? = "mtk-cpufreq",
};




5.7 調頻




/**********************************
* cpufreq target callback function
***********************************/
/*************************************************
* [note]
* 1. handle frequency change request
* 2. call mtk_cpufreq_set to set target frequency
**************************************************/
static int mtk_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation)
{
? ? …


? ? /******************************
? ? * look up the target frequency
? ? *******************************/
? ? if (cpufreq_frequency_table_target(policy, mtk_cpu_freqs_table, target_freq, relation, &idx))
? ? ? ? return -EINVAL;


? ?


//idx是目標調頻點索引值


? ? if (get_chip_ver() >= CHIP_6577_E1)
? ? {…
? ? }
? ? else if (get_chip_ver() >= CHIP_6575_E2)
? ? {
? ? ? ? next = &mt6575_freqs_e2[idx];
? ? }
? ? …
?
// next指向目標調頻點
// freqs.old是當前頻點,freqs.new是目標頻點
? ? freqs.old = policy->cur;
? ? freqs.new = next->cpufreq_mhz;
? ? freqs.cpu = policy->cpu;


? ??


? ? #ifndef MTK_DVFS_RANDOM_TEST
? ? if (mtk_cpufreq_keep_max_freq(freqs.old, freqs.new))
? ? {
? ? ? ? if ((DRV_Reg32(HW_RESV) & (0x1 << 23)) && ((DRV_Reg32(HW_RESV) & (0x1 << 20)) == 0))
? ? ? ? ? ? freqs.new = DVFS_F1_TM;
? ? ? ? else
? ? ? ? ? ? freqs.new = DVFS_F1;
? ? }


? ? if (freqs.new > g_limited_freq)
? ? {
? ? ? ? dprintk("CPU frequency has been limited to %d Mhz, request %d Mhz will be limited\n", g_limited_freq / 1000, freqs.new / 1000);
? ? ? ? freqs.new = g_limited_freq;
? ? }


? ? if (freqs.new < g_limited_min_freq)
? ? {
? ? ? ? dprintk("cannot switch CPU frequency to %d Mhz due to voltage limitation\n", g_limited_min_freq / 1000);
? ? ? ? freqs.new = g_limited_min_freq;
? ? }
? ? #endif


? ? /************************************************
? ? * target frequency == existing frequency, skip it
? ? *************************************************/
? ? if (freqs.old == freqs.new)
? ? {
? ? ? ? dprintk("CPU frequency from %d MHz to %d MHz (skipped) due to same frequency\n", freqs.old / 1000, freqs.new / 1000);
? ? ? ? return 0;
? ? }


/*調頻前對所有ONLINE CPU發出通知*/
? ? for_each_online_cpu(cpu)
? ? {
? ? ? ? freqs.cpu = cpu;
? ? ? ? cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
? ? }


? ? spin_lock_irqsave(&mtk_cpufreq_lock, flags);


? ? /*********************************************
? ? * update current frequency due to last change
? ? **********************************************/
? ? freqs.old = g_cur_freq;


? ? /******************************
? ? * set to the target freeuency
*******************************/
//真正的調頻操作
? ? mtk_cpufreq_set(freqs.old, freqs.new);


? ? spin_unlock_irqrestore(&mtk_cpufreq_lock, flags);




/*調頻后對所有ONLINE CPU發出通知*/


? ? for_each_online_cpu(cpu)
? ? {
? ? ? ? freqs.cpu = cpu;
? ? ? ? cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
? ? }


? ? return 0;
}








/*****************************************
* frequency ramp up and ramp down handler
******************************************/
/***********************************************************
* [note]
* 1. frequency ramp up need to wait voltage settle
* 2. frequency ramp down do not need to wait voltage settle
************************************************************/
static void mtk_cpufreq_set(unsigned int freq_old, unsigned int freq_new)
{
? ? if (freq_new == DVFS_F1 || freq_new == DVFS_F1_TM) /* set ARMPLL divider to 1/1 */
? ? {
? ? ? ? …
? ? }
? ? else if (freq_new == DVFS_F2 || freq_new == DVFS_F2_TM) /* set ARMPLL divider to 5/6 */
? ? {
? ? ? ? if (freq_new > freq_old)
? ? ? ? { ? ?//升頻,先調壓再調頻
//調壓
? ? ? ? ? ? #ifdef MTK_BUCK_ADJUST
? ? ? ? ? ? DRV_WriteReg32(SC_AP_DVFS_CON, ((DRV_Reg32(SC_AP_DVFS_CON) & 0xFFFFFFFC) | 0x03));


? ? ? ? ? ? mb();
? ? ? ? ? ? udelay(PMIC_SETTLE_TIME);
? ? ? ? ? ? #endif
? ? ? ? ? ?
? ? ? ? ? ??
? ? ? ? ? ? g_cur_freq = freq_new;
//調頻
? ? ? ? ? ? DRV_WriteReg32(TOP_CKDIV1, 0x19);
? ? ? ? }
? ? ? ? else
? ? ? ? { ? //降頻,先調頻再調壓
? ? ? ? ? ? //調頻
? ? ? ? ? ? g_cur_freq = freq_new;
? ? ? ? ? ? DRV_WriteReg32(TOP_CKDIV1, 0x19);
? ? ? ? ? ? mb();
? ? ? ? ? ? ?
//調壓
? ? ? ? ? ? #ifdef MTK_BUCK_ADJUST
? ? ? ? ? ? DRV_WriteReg32(SC_AP_DVFS_CON, ((DRV_Reg32(SC_AP_DVFS_CON) & 0xFFFFFFFC) | 0x03));
? ? ? ? ? ? #endif
? ? ? ? }
? ? }
? ? else if (freq_new == DVFS_F3 || freq_new == DVFS_F3_TM) /* set ARMPLL divider to 3/4 */
? ? {
? ? ??
? ? }
? ? else if (freq_new == DVFS_F4 || freq_new == DVFS_F4_TM) /* set ARMPLL divider to 2/3 */
? ? {
? ? }
? ? else if (freq_new == DVFS_F5 || freq_new == DVFS_F5_TM) /* set ARMPLL divider to 1/2 */
? ? {
? ? }
? ? else if (freq_new == DVFS_F6 || freq_new == DVFS_F6_TM) /* set ARMPLL divider to 1/4 */
? ? {
? ? }
? ? else if (freq_new == DVFS_F7 || freq_new == DVFS_F7_TM) /* set ARMPLL divider to 1/6 */
? ? {
? ? }
? ?


}




6 IRQ


6.1 中斷體系
根據arm gic規范,
0-15 SGI
16-31 PPP
32以上 SPI




6.3 外部中斷




typedef struct?
{
? ? void (*eint_func[EINT_MAX_CHANNEL])(void);
? ? unsigned int eint_auto_umask[EINT_MAX_CHANNEL];
} eint_func;




通過“void mt65xx_eint_registration(…)”注冊自己的中斷函數。


比如“alps\mediatek\custom\common\kernel\touchpanel\ft5206\ft5206_driver.c”通過該函數注冊自己的中斷處理函數:


? ? mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_POLARITY_HIGH, tpd_eint_interrupt_handler, 1);






外部中斷的入口是“static irqreturn_t mt65xx_eint_isr(int irq, void *dev_id)”,該函數會檢查“eint_func”數組里的處理函數。而整個外部中斷入口是由EINT_IRQ中斷觸發。在“alps\mediatek\platform\mt6577\kernel\core\mt6577_eint.c”將EINT_IRQ中斷掛入6577的中斷體系。


if (request_irq(EINT_IRQ, mt65xx_eint_isr, IRQF_TRIGGER_HIGH, "EINT", NULL)) {
? ? ? ? printk(KERN_ERR "EINT IRQ LINE NOT AVAILABLE!!\n");
}


6.4 wakeup
static u16 sc_wake_irq[NUM_WAKE_SRC] = {
[2] = MT6577_KP_IRQ_ID,
[3] = MT6577_MSDC1_IRQ_ID,
[5] = MT6577_EINT_IRQ_ID,
[6] = MT6577_RTC_IRQ_ID,
[7] = MT6577_AP_CCIF_IRQ_ID,
[8] = MT6577_ACCDET_IRQ_ID,
};


15 Driver




15.1 LCM
修改lps/mediatek/config/common/ProjectConfig.mk”里的“CUSTOM_KERNEL_LCM”和 “CUSTOM_UBOOT_LCM”選項將影響到文件“alps/mediatek/config/out/mt6577/ProjectConfig.mk”


將上述兩項CUSTOM_KERNEL_LCM=hx8369_6575 ?CUSTOM_UBOOT_LCM=hx8369_6575


導致


alps/mediatek/custom/common/kernel/lcm/hx8369_6575/hx8369_6575.c拷到如下兩個目錄




alps/mediatek/custom/out/mt6577/kernel/lcm


alps/mediatek/custom/out/mt6577/uboot/lcm






mediatek\source\kernel\drivers\video


static const DISP_DRIVER DSI_DISP_DRV








const LCM_DRIVER *disp_drv_get_lcm_driver(const char *lcm_name)






15.2 BL
mediatek\source\kernel\drivers\led\leds.c
{


if(strcmp(g_leds_data[i]->cdev.name,"lcd-backlight") == 0)
{
rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_duty);
? ? ? ? ? ? if(rc)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? LEDS_DEBUG("[LED]device_create_file duty fail!\n");
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ? ? ? ? rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_div);
? ? ? ? ? ? if(rc)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? LEDS_DEBUG("[LED]device_create_file duty fail!\n");
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ? ? ? ? rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_frequency);
? ? ? ? ? ? if(rc)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? LEDS_DEBUG("[LED]device_create_file duty fail!\n");
? ? ? ? ? ? }
? ? ? ? ? ??
? ?rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_pwm_register);
? ? ? ? ? ? if(rc)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? LEDS_DEBUG("[LED]device_create_file duty fail!\n");
? ? ? ? ? ? }
bl_setting = &g_leds_data[i]->cust;
}




}
static DEVICE_ATTR(duty, 0664, show_duty, store_duty);


g_leds_data






[ ? 40.450409] (0)[313:ScreenOffThread][LED]Set Backlight directly 102 at time 4294941336
[ ? 40.451398] (0)[313:ScreenOffThread]mt65xx_leds_set_cust: set brightness, name:lcd-backlight, mode:3, level:102
[ ? 40.452744] (0)[313:ScreenOffThread]brightness_set_pmic1[LED]PMIC#3:102
[ ? 40.454159] (0)[313:ScreenOffThread]brightness_set_pmic3 2




brightness_set_pmic


mt65xx_leds_brightness_set


led_brightness_set




15.3 TP


alps\mediatek\custom\common\kernel\touchpanel\ft5206
alps\mediatek\custom\common\kernel\touchpanel\src


15.5 Musb


15.5.1 配置
盡管在
mediatek/config/mt6577/autoconfig/kconfig/platform
CONFIG_USB_MTK_HDRC_HCD is not set
CONFIG_USB_MTK_OTG is not set


但是在
mediatek/config/mt6577/autoconfig/kconfig/project
CONFIG_USB_MTK_HDRC_HCD=y
CONFIG_USB_MTK_OTG=y




15.5.2 Platform device & driver


mediatek\platform\mt6577\kernel\core
struct platform_device mt_device_usb = {
.name ?= "mt_usb",
.id ?= -1,
.dev = { ? ? ? ? ? ? ? ?
//.platform_data ? ? ? ? ?= &usb_data_mt65xx, ? ??
.dma_mask ? ? ? ? ? ? ? = &usb_dmamask,
.coherent_dma_mask ? ? ?= DMA_BIT_MASK(32),?
//.release=musbfsh_hcd_release, ? ?
},
};






__init int mt6577_board_init(void)
{



#if defined(CONFIG_USB_MTK_HDRC)
printk("mt_device_usb register\n");
retval = platform_device_register(&mt_device_usb);
if (retval != 0){
printk("mt_device_usb register fail\n");
? ? ? ? return retval;
}
#endif

}












mediatek\source\kernel\drivers\usb20


static struct platform_driver musb_driver = {
.driver = {
.name = (char *)musb_driver_name,
.owner = THIS_MODULE,
},
.remove = __exit_p(musb_remove),
.shutdown = musb_shutdown,
.probe = musb_probe,
};
















data_array[0]=0x00103902;
? ? ? ? data_array[1]=0x032000B2;
? ? ? ? data_array[2]=0xFF007003;
? ? ? ? data_array[3]=0x00000000;
? ? ? ? data_array[4]=0x01000303;
? ? ? ? dsi_set_cmdq(&data_array, 5, 1);


? data_array[0] 為packet head ?定義為:第一個字節為 WC1,第二個字節WC0,第三個字節DT (命令類型)第四個字節為控制類型。


? data_array[1],data_array[2],data_array[3],data_array[4],為初始化的相應數據。








15.6 GPIO




GPIO初始化在uboot里完成




GPIO在內核的定義:
cust_gpio_usage.h






GPIO在內核的設置
mt_set_gpio_mode


15.7 IIC
15.7.1 ?adapter device


alps\mediatek\platform\mt6577\kernel\core\Mt6577_devs.c


static struct platform_device mt_device_i2c[] = {
? ? {
? ? ? ? .name ? ? ? ? ? = "mt-i2c",
? ? ? ? .id ? ? ? ? ? ? = 0,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt_resource_i2c1),
? ? ? ? .resource ? ? ? = mt_resource_i2c1,
? ? },

? ? {
? ? ? ? .name ? ? ? ? ? = "mt-i2c",
? ? ? ? .id ? ? ? ? ? ? = 2,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt_resource_i2c3),
? ? ? ? .resource ? ? ? = mt_resource_i2c3,
? ? },
};


15.7.2 adapter driver
alps\mediatek\platform\mt6577\kernel\drivers\i2c\I2c.c




static struct platform_driver mt_i2c_driver = {
? ? .probe = mt_i2c_probe,
? ? .remove = mt_i2c_remove,
#ifdef CONFIG_PM
? ? .suspend = mt_i2c_suspend,
? ? .resume = mt_i2c_resume,
#endif
? ? .driver ?= {
? ? ? ? .name ?= DRV_NAME,
? ? ? ? .owner = THIS_MODULE,
? ? },
};




15.7.3 匹配IIC通道


i2c_register_board_info




15.8 PMIC MT6329
alps\mediatek\platform\mt6577\kernel\drivers\power\pmic_mt6329.c


i2c_register_board_info 指出mt6329使用2通道




15.9 emmc & sd




C:\senix\rd\mtk\6577\source-code\src\alps\mediatek\platform\mt6577\kernel\core\ mt6577_devs.c


static struct platform_device mt6577_device_sd[] =
{
#if defined(CFG_DEV_MSDC0)
? ? {
? ? ? ? .name ? ? ? ? ? = "mtk-sd",
? ? ? ? .id ? ? ? ? ? ? = 0,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt6577_resource_sd0),
? ? ? ? .resource ? ? ? = mt6577_resource_sd0,
? ? ? ? .dev = {
? ? ? ? ? ? .platform_data = &msdc0_hw,
? ? ? ? },
? ? },
#endif
#if defined(CFG_DEV_MSDC1)
? ? {
? ? ? ? .name ? ? ? ? ? = "mtk-sd",
? ? ? ? .id ? ? ? ? ? ? = 1,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt6577_resource_sd1),
? ? ? ? .resource ? ? ? = mt6577_resource_sd1,
? ? ? ? .dev = {
? ? ? ? ? ? .platform_data = &msdc1_hw,
? ? ? ? },
? ? },
#endif
#if defined(CFG_DEV_MSDC2)
? ? {
? ? ? ? .name ? ? ? ? ? = "mtk-sd",
? ? ? ? .id ? ? ? ? ? ? = 2,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt6577_resource_sd2),
? ? ? ? .resource ? ? ? = mt6577_resource_sd2,
? ? ? ? .dev = {
? ? ? ? ? ? .platform_data = &msdc2_hw,
? ? ? ? },
? ? },
#endif
#if defined(CFG_DEV_MSDC3)
? ? {
? ? ? ? .name ? ? ? ? ? = "mtk-sd",
? ? ? ? .id ? ? ? ? ? ? = 3,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt6577_resource_sd3),
? ? ? ? .resource ? ? ? = mt6577_resource_sd3,
? ? ? ? .dev = {
? ? ? ? ? ? .platform_data = &msdc3_hw,
? ? ? ? },
? ? },
#endif
};




驅動
c:\senix\rd\mtk\6577\source-code\src\alps\mediatek\platform\mt6577\kernel\drivers\mmc-host\sd.c




EMMC數據線定義
struct msdc_hw msdc0_hw = {
? ?.clk_src ? ? ? ?= 1,
? ?.cmd_edge ? ? ? = MSDC_SMPL_FALLING,
? ?.data_edge ? ? ?= MSDC_SMPL_FALLING,
? ?…
? ?.data_pins ? ? ?= 8,
? ?.data_offset ? ?= 0,
#ifdef MTK_EMMC_SUPPORT
? ?.flags ? ? ? ? ?= MSDC_SYS_SUSPEND | MSDC_HIGHSPEED,
#else
? ?.flags ? ? ? ? ?= MSDC_SDCARD_FLAG,
#endif
};






static struct mmc_host_ops mt_msdc_ops = {
? ? .request ? ? ? ? = msdc_ops_request,
? ? .set_ios ? ? ? ? = msdc_ops_set_ios,
? ? .get_ro ? ? ? ? ?= msdc_ops_get_ro,
? ? .get_cd ? ? ? ? ?= msdc_ops_get_cd,
? ? .enable_sdio_irq = msdc_ops_enable_sdio_irq,
? ? .start_signal_voltage_switch = msdc_ops_switch_volt,
};




Host
Mmc card device
Mmc card driver


mmc_rescan 掃描mmc 家里mmc設備


mmc_init_card




mmc_blk_probe
?add_disk


總結

以上是生活随笔為你收集整理的mt6577驱动开发 笔记版 转载请注明出处---crosskernel@gmail.com的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。