diff options
Diffstat (limited to 'drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c')
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c | 442 |
1 files changed, 0 insertions, 442 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c deleted file mode 100644 index fa03b78c3580..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Support for Medifield PNW Camera Imaging ISP subsystem. - * - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * 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. - * - * - */ - -#include <media/v4l2-event.h> -#include <media/v4l2-mediabus.h> -#include "atomisp_cmd.h" -#include "atomisp_internal.h" -#include "atomisp-regs.h" - -static struct v4l2_mbus_framefmt *__csi2_get_format(struct - atomisp_mipi_csi2_device - *csi2, - struct - v4l2_subdev_pad_config *cfg, - enum - v4l2_subdev_format_whence - which, unsigned int pad) -{ - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&csi2->subdev, cfg, pad); - else - return &csi2->formats[pad]; -} - -/* - * csi2_enum_mbus_code - Handle pixel format enumeration - * @sd : pointer to v4l2 subdev structure - * @fh : V4L2 subdev file handle - * @code : pointer to v4l2_subdev_pad_mbus_code_enum structure - * return -EINVAL or zero on success -*/ -static int csi2_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) -{ - const struct atomisp_in_fmt_conv *ic = atomisp_in_fmt_conv; - unsigned int i = 0; - - while (ic->code) { - if (i == code->index) { - code->code = ic->code; - return 0; - } - i++, ic++; - } - - return -EINVAL; -} - -/* - * csi2_get_format - Handle get format by pads subdev method - * @sd : pointer to v4l2 subdev structure - * @fh : V4L2 subdev file handle - * @pad: pad num - * @fmt: pointer to v4l2 format structure - * return -EINVAL or zero on sucess -*/ -static int csi2_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) -{ - struct atomisp_mipi_csi2_device *csi2 = v4l2_get_subdevdata(sd); - struct v4l2_mbus_framefmt *format; - - format = __csi2_get_format(csi2, cfg, fmt->which, fmt->pad); - - fmt->format = *format; - - return 0; -} - -int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - unsigned int which, uint16_t pad, - struct v4l2_mbus_framefmt *ffmt) -{ - struct atomisp_mipi_csi2_device *csi2 = v4l2_get_subdevdata(sd); - struct v4l2_mbus_framefmt *actual_ffmt = -#ifndef ISP2401 - __csi2_get_format(csi2, cfg, which, pad); -#else - __csi2_get_format(csi2, cfg, which, pad); -#endif - - if (pad == CSI2_PAD_SINK) { - const struct atomisp_in_fmt_conv *ic; - struct v4l2_mbus_framefmt tmp_ffmt; - - ic = atomisp_find_in_fmt_conv(ffmt->code); - if (ic) - actual_ffmt->code = ic->code; - else - actual_ffmt->code = atomisp_in_fmt_conv[0].code; - - actual_ffmt->width = clamp_t( - u32, ffmt->width, ATOM_ISP_MIN_WIDTH, - ATOM_ISP_MAX_WIDTH); - actual_ffmt->height = clamp_t( - u32, ffmt->height, ATOM_ISP_MIN_HEIGHT, - ATOM_ISP_MAX_HEIGHT); - - tmp_ffmt = *ffmt = *actual_ffmt; - - return atomisp_csi2_set_ffmt(sd, cfg, which, CSI2_PAD_SOURCE, - &tmp_ffmt); - } - - /* FIXME: DPCM decompression */ - *actual_ffmt = *ffmt = -#ifndef ISP2401 - *__csi2_get_format(csi2, cfg, which, CSI2_PAD_SINK); -#else - *__csi2_get_format(csi2, cfg, which, CSI2_PAD_SINK); -#endif - - return 0; -} - -/* - * csi2_set_format - Handle set format by pads subdev method - * @sd : pointer to v4l2 subdev structure - * @fh : V4L2 subdev file handle - * @pad: pad num - * @fmt: pointer to v4l2 format structure - * return -EINVAL or zero on success -*/ -static int csi2_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) -{ - return atomisp_csi2_set_ffmt(sd, cfg, fmt->which, fmt->pad, - &fmt->format); -} - -/* - * csi2_set_stream - Enable/Disable streaming on the CSI2 module - * @sd: ISP CSI2 V4L2 subdevice - * @enable: Enable/disable stream (1/0) - * - * Return 0 on success or a negative error code otherwise. -*/ -static int csi2_set_stream(struct v4l2_subdev *sd, int enable) -{ - return 0; -} - -/* subdev core operations */ -static const struct v4l2_subdev_core_ops csi2_core_ops = { -}; - -/* subdev video operations */ -static const struct v4l2_subdev_video_ops csi2_video_ops = { - .s_stream = csi2_set_stream, -}; - -/* subdev pad operations */ -static const struct v4l2_subdev_pad_ops csi2_pad_ops = { - .enum_mbus_code = csi2_enum_mbus_code, - .get_fmt = csi2_get_format, - .set_fmt = csi2_set_format, - .link_validate = v4l2_subdev_link_validate_default, -}; - -/* subdev operations */ -static const struct v4l2_subdev_ops csi2_ops = { - .core = &csi2_core_ops, - .video = &csi2_video_ops, - .pad = &csi2_pad_ops, -}; - -#ifndef ISP2401 - -#endif -/* - * csi2_link_setup - Setup CSI2 connections. - * @entity : Pointer to media entity structure - * @local : Pointer to local pad array - * @remote : Pointer to remote pad array - * @flags : Link flags - * return -EINVAL or zero on success -*/ -static int csi2_link_setup(struct media_entity *entity, - const struct media_pad *local, - const struct media_pad *remote, u32 flags) -{ - struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); - struct atomisp_mipi_csi2_device *csi2 = v4l2_get_subdevdata(sd); - u32 result = local->index | is_media_entity_v4l2_subdev(remote->entity); - - switch (result) { - case CSI2_PAD_SOURCE | MEDIA_ENT_F_OLD_BASE: - /* not supported yet */ - return -EINVAL; - - case CSI2_PAD_SOURCE | MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN: - if (flags & MEDIA_LNK_FL_ENABLED) { - if (csi2->output & ~CSI2_OUTPUT_ISP_SUBDEV) - return -EBUSY; - csi2->output |= CSI2_OUTPUT_ISP_SUBDEV; - } else { - csi2->output &= ~CSI2_OUTPUT_ISP_SUBDEV; - } - break; - - default: - /* Link from camera to CSI2 is fixed... */ - return -EINVAL; - } - return 0; -} - -/* media operations */ -static const struct media_entity_operations csi2_media_ops = { - .link_setup = csi2_link_setup, - .link_validate = v4l2_subdev_link_validate, -}; - -/* -* ispcsi2_init_entities - Initialize subdev and media entity. -* @csi2: Pointer to ispcsi2 structure. -* return -ENOMEM or zero on success -*/ -static int mipi_csi2_init_entities(struct atomisp_mipi_csi2_device *csi2, - int port) -{ - struct v4l2_subdev *sd = &csi2->subdev; - struct media_pad *pads = csi2->pads; - struct media_entity *me = &sd->entity; - int ret; - - v4l2_subdev_init(sd, &csi2_ops); - snprintf(sd->name, sizeof(sd->name), "ATOM ISP CSI2-port%d", port); - - v4l2_set_subdevdata(sd, csi2); - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - - pads[CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; - pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK; - - me->ops = &csi2_media_ops; - me->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; - ret = media_entity_pads_init(me, CSI2_PADS_NUM, pads); - if (ret < 0) - return ret; - - csi2->formats[CSI2_PAD_SINK].code = - csi2->formats[CSI2_PAD_SOURCE].code = - atomisp_in_fmt_conv[0].code; - - return 0; -} - -void -atomisp_mipi_csi2_unregister_entities(struct atomisp_mipi_csi2_device *csi2) -{ - media_entity_cleanup(&csi2->subdev.entity); - v4l2_device_unregister_subdev(&csi2->subdev); -} - -int atomisp_mipi_csi2_register_entities(struct atomisp_mipi_csi2_device *csi2, - struct v4l2_device *vdev) -{ - int ret; - - /* Register the subdev and video nodes. */ - ret = v4l2_device_register_subdev(vdev, &csi2->subdev); - if (ret < 0) - goto error; - - return 0; - -error: - atomisp_mipi_csi2_unregister_entities(csi2); - return ret; -} - -static const int LIMIT_SHIFT = 6; /* Limit numeric range into 31 bits */ - -static int -atomisp_csi2_configure_calc(const short int coeffs[2], int mipi_freq, int def) -{ - /* Delay counter accuracy, 1/0.0625 for ANN/CHT, 1/0.125 for BXT */ - static const int accinv = 16; /* 1 / COUNT_ACC */ - int r; - - if (mipi_freq >> LIMIT_SHIFT <= 0) - return def; - - r = accinv * coeffs[1] * (500000000 >> LIMIT_SHIFT); - r /= mipi_freq >> LIMIT_SHIFT; - r += accinv * coeffs[0]; - - return r; -} - -static void atomisp_csi2_configure_isp2401(struct atomisp_sub_device *asd) -{ - /* - * The ISP2401 new input system CSI2+ receiver has several - * parameters affecting the receiver timings. These depend - * on the MIPI bus frequency F in Hz (sensor transmitter rate) - * as follows: - * register value = (A/1e9 + B * UI) / COUNT_ACC - * where - * UI = 1 / (2 * F) in seconds - * COUNT_ACC = counter accuracy in seconds - * For ANN and CHV, COUNT_ACC = 0.0625 ns - * For BXT, COUNT_ACC = 0.125 ns - * A and B are coefficients from the table below, - * depending whether the register minimum or maximum value is - * calculated. - * Minimum Maximum - * Clock lane A B A B - * reg_rx_csi_dly_cnt_termen_clane 0 0 38 0 - * reg_rx_csi_dly_cnt_settle_clane 95 -8 300 -16 - * Data lanes - * reg_rx_csi_dly_cnt_termen_dlane0 0 0 35 4 - * reg_rx_csi_dly_cnt_settle_dlane0 85 -2 145 -6 - * reg_rx_csi_dly_cnt_termen_dlane1 0 0 35 4 - * reg_rx_csi_dly_cnt_settle_dlane1 85 -2 145 -6 - * reg_rx_csi_dly_cnt_termen_dlane2 0 0 35 4 - * reg_rx_csi_dly_cnt_settle_dlane2 85 -2 145 -6 - * reg_rx_csi_dly_cnt_termen_dlane3 0 0 35 4 - * reg_rx_csi_dly_cnt_settle_dlane3 85 -2 145 -6 - * - * We use the minimum values in the calculations below. - */ - static const short int coeff_clk_termen[] = { 0, 0 }; - static const short int coeff_clk_settle[] = { 95, -8 }; - static const short int coeff_dat_termen[] = { 0, 0 }; - static const short int coeff_dat_settle[] = { 85, -2 }; - static const int TERMEN_DEFAULT = 0 * 0; - static const int SETTLE_DEFAULT = 0x480; - static const hrt_address csi2_port_base[] = { - [ATOMISP_CAMERA_PORT_PRIMARY] = CSI2_PORT_A_BASE, - [ATOMISP_CAMERA_PORT_SECONDARY] = CSI2_PORT_B_BASE, - [ATOMISP_CAMERA_PORT_TERTIARY] = CSI2_PORT_C_BASE, - }; - /* Number of lanes on each port, excluding clock lane */ - static const unsigned char csi2_port_lanes[] = { - [ATOMISP_CAMERA_PORT_PRIMARY] = 4, - [ATOMISP_CAMERA_PORT_SECONDARY] = 2, - [ATOMISP_CAMERA_PORT_TERTIARY] = 2, - }; - static const hrt_address csi2_lane_base[] = { - CSI2_LANE_CL_BASE, - CSI2_LANE_D0_BASE, - CSI2_LANE_D1_BASE, - CSI2_LANE_D2_BASE, - CSI2_LANE_D3_BASE, - }; - - int clk_termen; - int clk_settle; - int dat_termen; - int dat_settle; - - struct v4l2_control ctrl; - struct atomisp_device *isp = asd->isp; - struct camera_mipi_info *mipi_info; - int mipi_freq = 0; - enum atomisp_camera_port port; - - int n; - - mipi_info = atomisp_to_sensor_mipi_info( - isp->inputs[asd->input_curr].camera); - port = mipi_info->port; - - ctrl.id = V4L2_CID_LINK_FREQ; - if (v4l2_g_ctrl - (isp->inputs[asd->input_curr].camera->ctrl_handler, &ctrl) == 0) - mipi_freq = ctrl.value; - - clk_termen = atomisp_csi2_configure_calc(coeff_clk_termen, - mipi_freq, TERMEN_DEFAULT); - clk_settle = atomisp_csi2_configure_calc(coeff_clk_settle, - mipi_freq, SETTLE_DEFAULT); - dat_termen = atomisp_csi2_configure_calc(coeff_dat_termen, - mipi_freq, TERMEN_DEFAULT); - dat_settle = atomisp_csi2_configure_calc(coeff_dat_settle, - mipi_freq, SETTLE_DEFAULT); - for (n = 0; n < csi2_port_lanes[port] + 1; n++) { - hrt_address base = csi2_port_base[port] + csi2_lane_base[n]; - atomisp_store_uint32(base + CSI2_REG_RX_CSI_DLY_CNT_TERMEN, - n == 0 ? clk_termen : dat_termen); - atomisp_store_uint32(base + CSI2_REG_RX_CSI_DLY_CNT_SETTLE, - n == 0 ? clk_settle : dat_settle); - } -} - -void atomisp_csi2_configure(struct atomisp_sub_device *asd) -{ - if (IS_HWREVISION(asd->isp, ATOMISP_HW_REVISION_ISP2401)) - atomisp_csi2_configure_isp2401(asd); -} - -/* - * atomisp_mipi_csi2_cleanup - Routine for module driver cleanup -*/ -void atomisp_mipi_csi2_cleanup(struct atomisp_device *isp) -{ -} - -#ifndef ISP2401 - -#endif -int atomisp_mipi_csi2_init(struct atomisp_device *isp) -{ - struct atomisp_mipi_csi2_device *csi2_port; - unsigned int i; - int ret; - - for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) { - csi2_port = &isp->csi2_port[i]; - csi2_port->isp = isp; - ret = mipi_csi2_init_entities(csi2_port, i); - if (ret < 0) - goto fail; - } - - return 0; - -fail: - atomisp_mipi_csi2_cleanup(isp); - return ret; -} - |