| /* |
| * arch/arm/plat-ambarella/generic/pll_hal.c |
| * |
| * Author: Cao Rongrong, <rrcao@ambarella.com> |
| * |
| * Copyright (C) 2004-2009, Ambarella, Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| * |
| */ |
| |
| #include <linux/kernel.h> |
| #include <linux/init.h> |
| #include <linux/platform_device.h> |
| #include <linux/bootmem.h> |
| #include <linux/delay.h> |
| #include <linux/irq.h> |
| #include <linux/dma-mapping.h> |
| #include <linux/proc_fs.h> |
| #include <linux/cpu.h> |
| |
| #include <asm/uaccess.h> |
| #include <asm/localtimer.h> |
| |
| #include <mach/hardware.h> |
| |
| #include <plat/pll.h> |
| #include <plat/timer.h> |
| #include <plat/ambcache.h> |
| |
| #include <hal/hal.h> |
| |
| /* ==========================================================================*/ |
| struct ambarella_pll_info { |
| amb_operating_mode_t operating_mode; |
| }; |
| |
| #if (CHIP_REV == A7 || CHIP_REV == I1) |
| struct ambarella_pll_vidcap_info { |
| char *name; |
| unsigned int vidcap; |
| }; |
| #endif |
| |
| struct ambarella_pll_mode_info { |
| char *name; |
| unsigned int mode; |
| }; |
| |
| struct ambarella_pll_performance_info { |
| char *name; |
| unsigned int performance; |
| }; |
| |
| /* ==========================================================================*/ |
| static struct proc_dir_entry *mode_file = NULL; |
| static struct proc_dir_entry *performance_file = NULL; |
| static struct ambarella_pll_info pll_info; |
| |
| #if (CHIP_REV == A5S) |
| #define AMB_OPERATING_MODE_END (AMB_OPERATING_MODE_IP_CAM_HP3 + 1) |
| static struct ambarella_pll_mode_info mode_list[] = { |
| {"3d_playback", AMB_OPERATING_MODE_3D_PLAYBACK}, |
| {"preview", AMB_OPERATING_MODE_PREVIEW}, |
| {"still_capture", AMB_OPERATING_MODE_STILL_CAPTURE}, |
| {"capture_nopreview", AMB_OPERATING_MODE_CAPTURE_NOPREVIEW}, |
| {"capture", AMB_OPERATING_MODE_CAPTURE}, |
| {"playback", AMB_OPERATING_MODE_PLAYBACK}, |
| {"display_and_arm", AMB_OPERATING_MODE_DISPLAY_AND_ARM}, |
| {"standby", AMB_OPERATING_MODE_STANDBY}, |
| {"lcd_bypass", AMB_OPERATING_MODE_LCD_BYPASS}, |
| {"still_preview", AMB_OPERATING_MODE_STILL_PREVIEW}, |
| {"lowpower", AMB_OPERATING_MODE_LOW_POWER}, |
| {"raw", AMB_OPERATING_MODE_RAW}, |
| {"ipcam", AMB_OPERATING_MODE_IP_CAM}, |
| {"ipcam_HP", AMB_OPERATING_MODE_IP_CAM_HP}, |
| {"ipcam_HP1_372MHZ", AMB_OPERATING_MODE_IP_CAM_HP1}, |
| {"ipcam_HP2_384MHZ", AMB_OPERATING_MODE_IP_CAM_HP2}, |
| {"ipcam_HP3_396MHZ", AMB_OPERATING_MODE_IP_CAM_HP3}, |
| }; |
| #define AMB_OPERATING_PERFORMANCE_END (AMB_PERFORMANCE_2160P60) |
| static struct ambarella_pll_performance_info performance_list[] = { |
| {"480P30", AMB_PERFORMANCE_480P30}, |
| {"720P30", AMB_PERFORMANCE_720P30}, |
| {"720P60", AMB_PERFORMANCE_720P60}, |
| {"1080I60_LowPower", AMB_PERFORMANCE_1080I60_LP}, |
| {"1080I60", AMB_PERFORMANCE_1080I60}, |
| {"1080P30", AMB_PERFORMANCE_1080P30}, |
| {"1080P50", AMB_PERFORMANCE_1080P50}, |
| {"1080P60", AMB_PERFORMANCE_1080P60}, |
| }; |
| |
| #elif (CHIP_REV == A7) |
| static struct proc_dir_entry *vidcap_file = NULL; |
| #define AMB_OPERATING_MODE_END (AMB_OPERATING_MODE_IP_CAM + 1) |
| static struct ambarella_pll_mode_info mode_list[] = { |
| {"preview", AMB_OPERATING_MODE_PREVIEW}, |
| {"still_capture", AMB_OPERATING_MODE_STILL_CAPTURE}, |
| {"capture", AMB_OPERATING_MODE_CAPTURE}, |
| {"playback", AMB_OPERATING_MODE_PLAYBACK}, |
| {"display_and_arm", AMB_OPERATING_MODE_DISPLAY_AND_ARM}, |
| {"standby", AMB_OPERATING_MODE_STANDBY}, |
| {"lcd_bypass", AMB_OPERATING_MODE_LCD_BYPASS}, |
| {"still_preview", AMB_OPERATING_MODE_STILL_PREVIEW}, |
| {"lowpower", AMB_OPERATING_MODE_LOW_POWER}, |
| {"ipcam", AMB_OPERATING_MODE_IP_CAM}, |
| }; |
| #define AMB_OPERATING_PERFORMANCE_END (AMB_PERFORMANCE_2160P60) |
| static struct ambarella_pll_performance_info performance_list[] = { |
| {"480P30", AMB_PERFORMANCE_480P30}, |
| {"720P30", AMB_PERFORMANCE_720P30}, |
| {"720P60", AMB_PERFORMANCE_720P60}, |
| {"1080I60", AMB_PERFORMANCE_1080I60}, |
| {"1080P30", AMB_PERFORMANCE_1080P30}, |
| {"1080P60", AMB_PERFORMANCE_1080P60}, |
| }; |
| #define AMB_OPERATING_VIDCAP_END (AMB_VIDCAP_1536X384_SMALL_VB) |
| static struct ambarella_pll_vidcap_info vidcap_list[] = { |
| {"4096x3575", AMB_VIDCAP_4096X3575}, |
| {"4000x2250", AMB_VIDCAP_4000X2250}, |
| {"2304x1296", AMB_VIDCAP_2304X1296}, |
| {"1984x1116", AMB_VIDCAP_1984X1116}, |
| {"2048x1536", AMB_VIDCAP_2048X1536}, |
| {"1312x984", AMB_VIDCAP_1312X984}, |
| {"1536x384", AMB_VIDCAP_1536X384}, |
| {"1536x384_small_vb", AMB_VIDCAP_1536X384_SMALL_VB}, |
| }; |
| |
| #elif (CHIP_REV == I1) |
| static struct proc_dir_entry *vidcap_file = NULL; |
| #define AMB_OPERATING_MODE_END (AMB_OPERATING_MODE_AUDIO_CAPTURE + 1) |
| static struct ambarella_pll_mode_info mode_list[] = { |
| {"preview", AMB_OPERATING_MODE_PREVIEW}, |
| {"still_capture", AMB_OPERATING_MODE_STILL_CAPTURE}, |
| {"capture", AMB_OPERATING_MODE_CAPTURE}, |
| {"playback", AMB_OPERATING_MODE_PLAYBACK}, |
| {"display_and_arm", AMB_OPERATING_MODE_DISPLAY_AND_ARM}, |
| {"standby", AMB_OPERATING_MODE_STANDBY}, |
| {"lcd_bypass", AMB_OPERATING_MODE_LCD_BYPASS}, |
| {"still_preview", AMB_OPERATING_MODE_STILL_PREVIEW}, |
| {"lowpower", AMB_OPERATING_MODE_LOW_POWER}, |
| {"lowpower_cortex", AMB_OPERATING_MODE_LOW_POWER_WITH_CORTEX}, |
| {"auido_playback", AMB_OPERATING_MODE_AUDIO_PLAYBACK}, |
| {"auido_capture", AMB_OPERATING_MODE_AUDIO_CAPTURE}, |
| }; |
| #define AMB_OPERATING_PERFORMANCE_END (AMB_PERFORMANCE_2160P60) |
| static struct ambarella_pll_performance_info performance_list[] = { |
| {"480P30", AMB_PERFORMANCE_480P30}, |
| {"720P30", AMB_PERFORMANCE_720P30}, |
| {"720P60", AMB_PERFORMANCE_720P60}, |
| {"1080I60", AMB_PERFORMANCE_1080I60}, |
| {"1080P30", AMB_PERFORMANCE_1080P30}, |
| {"1080P60", AMB_PERFORMANCE_1080P60}, |
| }; |
| #define AMB_OPERATING_VIDCAP_END (AMB_VIDCAP_1088X816) |
| static struct ambarella_pll_vidcap_info vidcap_list[] = { |
| {"2304x1296_60fps", AMB_VIDCAP_2304X1296_60FPS}, |
| {"1296x1787", AMB_VIDCAP_1296X1787}, |
| {"2048x1536", AMB_VIDCAP_2048X1536}, |
| {"2240x1260", AMB_VIDCAP_2240X1260}, |
| {"1984x1116", AMB_VIDCAP_1984X1116}, |
| {"2112x1188", AMB_VIDCAP_2112X1188}, |
| {"1312x984", AMB_VIDCAP_1312X984}, |
| {"1088x816", AMB_VIDCAP_1088X816}, |
| }; |
| #endif |
| |
| /* ==========================================================================*/ |
| static int ambarella_pll_proc_read(char *page, char **start, |
| off_t off, int count, int *eof, void *data) |
| { |
| amb_hal_success_t result; |
| amb_operating_mode_t operating_mode; |
| int retlen = 0; |
| int i; |
| |
| result = amb_get_operating_mode(HAL_BASE_VP, &operating_mode); |
| if(result != AMB_HAL_SUCCESS){ |
| pr_err("%s: amb_get_operating_mode failed(%d)\n", |
| __func__, result); |
| retlen = -EPERM; |
| goto ambarella_pll_proc_read_exit; |
| } |
| |
| if (off != 0) { |
| retlen = 0; |
| goto ambarella_pll_proc_read_exit; |
| } |
| |
| #if (CHIP_REV == A7 || CHIP_REV == I1) |
| retlen += scnprintf((page + retlen), (count - retlen), |
| "\nPossible Vidcap:\n"); |
| for (i = 0; i < ARRAY_SIZE(vidcap_list); i++) { |
| retlen += scnprintf((page + retlen), (count - retlen), |
| "\t%s\n", vidcap_list[i].name); |
| } |
| #endif |
| retlen += scnprintf((page + retlen), (count - retlen), |
| "\nPossible Mode:\n"); |
| for (i = 0; i < ARRAY_SIZE(mode_list); i++) { |
| retlen += scnprintf((page + retlen), (count - retlen), |
| "\t%s\n", mode_list[i].name); |
| } |
| |
| retlen += scnprintf((page + retlen), (count - retlen), |
| "\nPossible Performance:\n"); |
| for (i = 0; i < ARRAY_SIZE(performance_list); i++) { |
| retlen += scnprintf((page + retlen), (count - retlen), |
| "\t%s\n", performance_list[i].name); |
| } |
| |
| retlen += scnprintf((page + retlen), (count - retlen), |
| "\nPLL Information:\n" |
| #if (CHIP_REV == A7 || CHIP_REV == I1) |
| "\tVidcap:\t\t%s\n" |
| #endif |
| "\tPerformance:\t%s\n" |
| "\tMode:\t\t%s\n" |
| "\tUSB:\t\t%s\n" |
| "\tHDMI:\t\t%s\n" |
| "\tDualStream:\t%s\n" |
| #if (CHIP_REV == A5S) |
| "\tHDpreview:\t%s\n" |
| #endif |
| #if (CHIP_REV == A7 || CHIP_REV == I1) |
| "\tDigitalGamma:\t%s\n" |
| #endif |
| "\tARM:\t\t%u Hz\n" |
| "\tDram:\t\t%u Hz\n" |
| "\tiDSP:\t\t%u Hz\n" |
| "\tCore:\t\t%u Hz\n" |
| #if (CHIP_REV == I1) |
| "\tCortex:\t\t%u Hz\n" |
| "\tAXI:\t\t%u Hz\n" |
| "\tDDD:\t\t%u Hz\n" |
| #endif |
| "\tAHB:\t\t%u Hz\n" |
| "\tAPB:\t\t%u Hz\n" |
| "\tVOUT:\t\t%u Hz\n" |
| "\tVOUT2:\t\t%u Hz\n" |
| "\tVIN:\t\t%u Hz\n" |
| "\tHDMI:\t\t%u Hz\n" |
| "\tAudio:\t\t%u Hz\n" |
| "\tADC:\t\t%u Hz\n" |
| "\tSSI:\t\t%u Hz\n" |
| "\tSSI2:\t\t%u Hz\n" |
| "\tUART:\t\t%u Hz\n" |
| #if (CHIP_REV == I1) |
| "\tGTX:\t\t%u Hz\n" |
| "\tSDXC:\t\t%u Hz\n" |
| #endif |
| "\tSD:\t\t%u Hz\n\n", |
| #if (CHIP_REV == A7 || CHIP_REV == I1) |
| vidcap_list[operating_mode.vidcap_size].name, |
| #endif |
| performance_list[operating_mode.performance].name, |
| mode_list[operating_mode.mode].name, |
| operating_mode.usb_state ? "On" : "Off", |
| operating_mode.hdmi_state ? "On" : "Off", |
| operating_mode.dual_stream_state ? "On" : "Off", |
| #if (CHIP_REV == A5S) |
| operating_mode.hd_preview_state ? "On" : "Off", |
| #endif |
| #if (CHIP_REV == A7 || CHIP_REV == I1) |
| operating_mode.amb_digital_gamma_mode ? "On" : "Off", |
| #endif |
| get_arm_bus_freq_hz(), |
| get_dram_freq_hz(), |
| get_idsp_freq_hz(), |
| get_core_bus_freq_hz(), |
| #if (CHIP_REV == I1) |
| amb_get_cortex_clock_frequency(HAL_BASE_VP), |
| amb_get_axi_clock_frequency(HAL_BASE_VP), |
| amb_get_3d_clock_frequency(HAL_BASE_VP), |
| #endif |
| get_ahb_bus_freq_hz(), |
| get_apb_bus_freq_hz(), |
| get_vout_freq_hz(), |
| get_vout2_freq_hz(), |
| get_so_freq_hz(), |
| amb_get_hdmi_clock_frequency(HAL_BASE_VP), |
| amb_get_audio_clock_frequency(HAL_BASE_VP), |
| amb_get_adc_clock_frequency(HAL_BASE_VP), |
| amb_get_ssi_clock_frequency(HAL_BASE_VP), |
| amb_get_ssi2_clock_frequency(HAL_BASE_VP), |
| amb_get_uart_clock_frequency(HAL_BASE_VP), |
| #if (CHIP_REV == I1) |
| amb_get_gtx_clock_frequency(HAL_BASE_VP), |
| amb_get_sdxc_clock_frequency(HAL_BASE_VP), |
| #endif |
| get_sd_freq_hz()); |
| |
| *eof = 1; |
| |
| ambarella_pll_proc_read_exit: |
| return retlen; |
| } |
| |
| int ambarella_set_operating_mode(amb_operating_mode_t *popmode) |
| { |
| int retval = 0; |
| amb_hal_success_t result = AMB_HAL_SUCCESS; |
| unsigned int oldfreq, newfreq; |
| unsigned long flags; |
| |
| retval = notifier_to_errno( |
| ambarella_set_event(AMBA_EVENT_PRE_CPUFREQ, NULL)); |
| if (retval) { |
| pr_err("%s: AMBA_EVENT_PRE_CPUFREQ failed(%d)\n", |
| __func__, retval); |
| } |
| |
| disable_nonboot_cpus(); |
| local_irq_save(flags); |
| |
| retval = notifier_to_errno( |
| ambarella_set_raw_event(AMBA_EVENT_PRE_CPUFREQ, NULL)); |
| if (retval) { |
| pr_err("%s: AMBA_EVENT_PRE_CPUFREQ failed(%d)\n", |
| __func__, retval); |
| } |
| |
| oldfreq = get_arm_bus_freq_hz(); |
| |
| ambarella_timer_suspend(1); |
| ambcache_pli_range(HAL_BASE_VP, ambarella_hal_get_size()); |
| result = amb_set_operating_mode(HAL_BASE_VP, popmode); |
| if (result != AMB_HAL_SUCCESS) { |
| pr_err("%s: amb_set_operating_mode failed(%d)\n", |
| __func__, result); |
| retval = -EPERM; |
| } |
| ambarella_timer_resume(1); |
| |
| newfreq = get_arm_bus_freq_hz(); |
| ambarella_adjust_jiffies(AMBA_EVENT_POST_CPUFREQ, oldfreq, newfreq); |
| |
| retval = notifier_to_errno( |
| ambarella_set_raw_event(AMBA_EVENT_POST_CPUFREQ, NULL)); |
| if (retval) { |
| pr_err("%s: AMBA_EVENT_POST_CPUFREQ failed(%d)\n", |
| __func__, retval); |
| } |
| |
| local_irq_restore(flags); |
| enable_nonboot_cpus(); |
| |
| retval = notifier_to_errno( |
| ambarella_set_event(AMBA_EVENT_POST_CPUFREQ, NULL)); |
| if (retval) { |
| pr_err("%s: AMBA_EVENT_POST_CPUFREQ failed(%d)\n", |
| __func__, retval); |
| } |
| |
| result = amb_get_operating_mode(HAL_BASE_VP, popmode); |
| if (result != AMB_HAL_SUCCESS) { |
| pr_err("%s: amb_get_operating_mode failed(%d)\n", |
| __func__, result); |
| retval = -EPERM; |
| } |
| |
| return retval; |
| } |
| |
| static int ambarella_mode_proc_write(struct file *file, |
| const char __user *buffer, unsigned long count, void *data) |
| { |
| int retval = 0; |
| char str[AMBPLL_MAX_CMD_LENGTH]; |
| int mode, i; |
| amb_hal_success_t result; |
| |
| i = (count < AMBPLL_MAX_CMD_LENGTH) ? count : AMBPLL_MAX_CMD_LENGTH; |
| if (copy_from_user(str, buffer, i)) { |
| pr_err("%s: copy_from_user fail!\n", __func__); |
| retval = -EFAULT; |
| goto ambarella_mode_proc_write_exit; |
| } |
| str[i - 1] = 0; |
| |
| mode = AMB_OPERATING_MODE_END; |
| for (i = 0; i < ARRAY_SIZE(mode_list); i++) { |
| if (strlen(str) == strlen(mode_list[i].name) |
| && strcmp(str, mode_list[i].name) == 0) { |
| mode = mode_list[i].mode; |
| break; |
| } |
| } |
| if (mode >= AMB_OPERATING_MODE_END) { |
| pr_err("%s: invalid mode (%s)!\n", __func__, str); |
| retval = -EINVAL; |
| goto ambarella_mode_proc_write_exit; |
| } |
| |
| result = amb_get_operating_mode(HAL_BASE_VP, &pll_info.operating_mode); |
| if(result != AMB_HAL_SUCCESS){ |
| pr_err("%s: amb_get_operating_mode failed(%d)\n", |
| __func__, result); |
| retval = -EPERM; |
| goto ambarella_mode_proc_write_exit; |
| } |
| |
| if (pll_info.operating_mode.mode != mode) { |
| pll_info.operating_mode.mode = mode; |
| retval = ambarella_set_operating_mode(&pll_info.operating_mode); |
| } |
| if (!retval) |
| retval = count; |
| |
| ambarella_mode_proc_write_exit: |
| return retval; |
| } |
| |
| static int ambarella_performance_proc_write(struct file *file, |
| const char __user *buffer, unsigned long count, void *data) |
| { |
| int retval = 0; |
| char str[AMBPLL_MAX_CMD_LENGTH]; |
| int performance, i; |
| amb_hal_success_t result; |
| |
| i = (count < AMBPLL_MAX_CMD_LENGTH) ? count : AMBPLL_MAX_CMD_LENGTH; |
| if (copy_from_user(str, buffer, i)) { |
| pr_err("%s: copy_from_user fail!\n", __func__); |
| retval = -EFAULT; |
| goto ambarella_performance_proc_write_exit; |
| } |
| str[i - 1] = 0; |
| |
| performance = AMB_OPERATING_PERFORMANCE_END; |
| for (i = 0; i < ARRAY_SIZE(performance_list); i++) { |
| if (strlen(str) == strlen(performance_list[i].name) |
| && strcmp(str, performance_list[i].name) == 0) { |
| performance = performance_list[i].performance; |
| break; |
| } |
| } |
| if (performance >= AMB_OPERATING_PERFORMANCE_END){ |
| pr_err("\n%s: invalid performance (%s)!\n", __func__, str); |
| retval = -EINVAL; |
| goto ambarella_performance_proc_write_exit; |
| } |
| |
| result = amb_get_operating_mode(HAL_BASE_VP, &pll_info.operating_mode); |
| if(result != AMB_HAL_SUCCESS){ |
| pr_err("%s: amb_get_operating_mode failed(%d)\n", |
| __func__, result); |
| retval = -EPERM; |
| goto ambarella_performance_proc_write_exit; |
| } |
| |
| if (pll_info.operating_mode.performance != performance) { |
| pll_info.operating_mode.performance = performance; |
| retval = ambarella_set_operating_mode(&pll_info.operating_mode); |
| } |
| if (!retval) |
| retval = count; |
| |
| ambarella_performance_proc_write_exit: |
| return retval; |
| } |
| |
| #if (CHIP_REV == A7 || CHIP_REV == I1) |
| static int ambarella_vidcap_proc_write(struct file *file, |
| const char __user *buffer, unsigned long count, void *data) |
| { |
| int retval = 0; |
| char str[AMBPLL_MAX_CMD_LENGTH]; |
| int vidcap, i; |
| amb_hal_success_t result; |
| |
| i = (count < AMBPLL_MAX_CMD_LENGTH) ? count : AMBPLL_MAX_CMD_LENGTH; |
| if (copy_from_user(str, buffer, i)) { |
| pr_err("%s: copy_from_user fail!\n", __func__); |
| retval = -EFAULT; |
| goto ambarella_vidcap_proc_write_exit; |
| } |
| str[i - 1] = 0; |
| |
| vidcap = AMB_OPERATING_VIDCAP_END; |
| for (i = 0; i < ARRAY_SIZE(vidcap_list); i++) { |
| if (strlen(str) == strlen(vidcap_list[i].name) |
| && strcmp(str, vidcap_list[i].name) == 0) { |
| vidcap = vidcap_list[i].vidcap; |
| break; |
| } |
| } |
| if (vidcap >= AMB_OPERATING_VIDCAP_END){ |
| pr_err("\n%s: invalid vidcap (%s)!\n", __func__, str); |
| retval = -EINVAL; |
| goto ambarella_vidcap_proc_write_exit; |
| } |
| |
| result = amb_get_operating_mode(HAL_BASE_VP, &pll_info.operating_mode); |
| if(result != AMB_HAL_SUCCESS){ |
| pr_err("%s: amb_get_operating_mode failed(%d)\n", |
| __func__, result); |
| retval = -EPERM; |
| goto ambarella_vidcap_proc_write_exit; |
| } |
| |
| if (pll_info.operating_mode.vidcap_size != vidcap) { |
| pll_info.operating_mode.vidcap_size = vidcap; |
| retval = ambarella_set_operating_mode(&pll_info.operating_mode); |
| } |
| if (!retval) |
| retval = count; |
| |
| ambarella_vidcap_proc_write_exit: |
| return retval; |
| } |
| #endif |
| |
| static int __init ambarella_init_pll_hal(void) |
| { |
| amb_hal_success_t result; |
| int retval = 0; |
| |
| result = amb_get_operating_mode(HAL_BASE_VP, &pll_info.operating_mode); |
| if(result != AMB_HAL_SUCCESS){ |
| pr_err("%s: get operating mode failed(%d)\n",__func__, result); |
| retval = -EPERM; |
| goto ambarella_init_pll_hal_exit; |
| } |
| |
| #if (CHIP_REV == A7 || CHIP_REV == I1) |
| vidcap_file = create_proc_entry("vidcap", S_IRUGO | S_IWUSR, |
| get_ambarella_proc_dir()); |
| if (vidcap_file == NULL) { |
| retval = -ENOMEM; |
| pr_err("%s: create proc file (vidcap) fail!\n", __func__); |
| goto ambarella_init_pll_hal_exit; |
| } else { |
| vidcap_file->read_proc = ambarella_pll_proc_read; |
| vidcap_file->write_proc = ambarella_vidcap_proc_write; |
| } |
| #endif |
| |
| mode_file = create_proc_entry("mode", S_IRUGO | S_IWUSR, |
| get_ambarella_proc_dir()); |
| if (mode_file == NULL) { |
| retval = -ENOMEM; |
| pr_err("%s: create proc file (mode) fail!\n", __func__); |
| goto ambarella_init_pll_hal_exit; |
| } else { |
| mode_file->read_proc = ambarella_pll_proc_read; |
| mode_file->write_proc = ambarella_mode_proc_write; |
| } |
| |
| performance_file = create_proc_entry("performance", S_IRUGO | S_IWUSR, |
| get_ambarella_proc_dir()); |
| if (performance_file == NULL) { |
| retval = -ENOMEM; |
| pr_err("%s: create proc file (performance) fail!\n", __func__); |
| goto ambarella_init_pll_hal_exit; |
| } else { |
| performance_file->read_proc = ambarella_pll_proc_read; |
| performance_file->write_proc = ambarella_performance_proc_write; |
| } |
| |
| ambarella_init_pll_hal_exit: |
| return retval; |
| } |
| |
| int __init ambarella_init_pll(void) |
| { |
| int retval = 0; |
| |
| retval = ambarella_init_pll_hal(); |
| |
| return retval; |
| } |
| |
| /* ==========================================================================*/ |
| u32 ambarella_pll_suspend(u32 level) |
| { |
| return 0; |
| } |
| |
| u32 ambarella_pll_resume(u32 level) |
| { |
| #if 1 |
| return 0; |
| #else |
| return amb_set_operating_mode(HAL_BASE_VP, &pll_info.operating_mode); |
| #endif |
| } |
| |