drivers/media/platform/samsung/s3c-camif/camif-core.c
Source file repositories/reference/linux-study-clean/drivers/media/platform/samsung/s3c-camif/camif-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/platform/samsung/s3c-camif/camif-core.c- Extension
.c- Size
- 15330 bytes
- Lines
- 648
- Domain
- Driver Families
- Bucket
- drivers/media
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bug.hlinux/clk.hlinux/delay.hlinux/device.hlinux/errno.hlinux/gpio.hlinux/i2c.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/list.hlinux/module.hlinux/platform_device.hlinux/pm_runtime.hlinux/slab.hlinux/types.hmedia/media-device.hmedia/v4l2-ctrls.hmedia/v4l2-ioctl.hmedia/videobuf2-v4l2.hmedia/videobuf2-dma-contig.hcamif-core.h
Detected Declarations
function s3c_camif_find_formatfunction camif_get_scaler_factorfunction s3c_camif_get_scaler_configfunction camif_register_sensorfunction camif_unregister_sensorfunction camif_create_media_linksfunction camif_register_video_nodesfunction camif_unregister_video_nodesfunction camif_unregister_media_entitiesfunction camif_media_dev_initfunction camif_clk_putfunction camif_clk_getfunction pathfunction s3c_camif_probefunction s3c_camif_removefunction s3c_camif_runtime_resumefunction s3c_camif_runtime_suspend
Annotated Snippet
if (src >= tar * tmp) {
*shift = sh;
*ratio = tmp;
return 0;
}
}
*shift = 0;
*ratio = 1;
return 0;
}
int s3c_camif_get_scaler_config(struct camif_vp *vp,
struct camif_scaler *scaler)
{
struct v4l2_rect *camif_crop = &vp->camif->camif_crop;
int source_x = camif_crop->width;
int source_y = camif_crop->height;
int target_x = vp->out_frame.rect.width;
int target_y = vp->out_frame.rect.height;
int ret;
if (vp->rotation == 90 || vp->rotation == 270)
swap(target_x, target_y);
ret = camif_get_scaler_factor(source_x, target_x, &scaler->pre_h_ratio,
&scaler->h_shift);
if (ret < 0)
return ret;
ret = camif_get_scaler_factor(source_y, target_y, &scaler->pre_v_ratio,
&scaler->v_shift);
if (ret < 0)
return ret;
scaler->pre_dst_width = source_x / scaler->pre_h_ratio;
scaler->pre_dst_height = source_y / scaler->pre_v_ratio;
scaler->main_h_ratio = (source_x << 8) / (target_x << scaler->h_shift);
scaler->main_v_ratio = (source_y << 8) / (target_y << scaler->v_shift);
scaler->scaleup_h = (target_x >= source_x);
scaler->scaleup_v = (target_y >= source_y);
scaler->copy = 0;
pr_debug("H: ratio: %u, shift: %u. V: ratio: %u, shift: %u.\n",
scaler->pre_h_ratio, scaler->h_shift,
scaler->pre_v_ratio, scaler->v_shift);
pr_debug("Source: %dx%d, Target: %dx%d, scaleup_h/v: %d/%d\n",
source_x, source_y, target_x, target_y,
scaler->scaleup_h, scaler->scaleup_v);
return 0;
}
static int camif_register_sensor(struct camif_dev *camif)
{
struct s3c_camif_sensor_info *sensor = &camif->pdata.sensor;
struct v4l2_device *v4l2_dev = &camif->v4l2_dev;
struct i2c_adapter *adapter;
struct v4l2_subdev_format format = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
};
struct v4l2_subdev *sd;
int ret;
camif->sensor.sd = NULL;
if (sensor->i2c_board_info.addr == 0)
return -EINVAL;
adapter = i2c_get_adapter(sensor->i2c_bus_num);
if (adapter == NULL) {
v4l2_warn(v4l2_dev, "failed to get I2C adapter %d\n",
sensor->i2c_bus_num);
return -EPROBE_DEFER;
}
sd = v4l2_i2c_new_subdev_board(v4l2_dev, adapter,
&sensor->i2c_board_info, NULL);
if (sd == NULL) {
i2c_put_adapter(adapter);
v4l2_warn(v4l2_dev, "failed to acquire subdev %s\n",
sensor->i2c_board_info.type);
return -EPROBE_DEFER;
}
camif->sensor.sd = sd;
v4l2_info(v4l2_dev, "registered sensor subdevice %s\n", sd->name);
Annotation
- Immediate include surface: `linux/bug.h`, `linux/clk.h`, `linux/delay.h`, `linux/device.h`, `linux/errno.h`, `linux/gpio.h`, `linux/i2c.h`, `linux/interrupt.h`.
- Detected declarations: `function s3c_camif_find_format`, `function camif_get_scaler_factor`, `function s3c_camif_get_scaler_config`, `function camif_register_sensor`, `function camif_unregister_sensor`, `function camif_create_media_links`, `function camif_register_video_nodes`, `function camif_unregister_video_nodes`, `function camif_unregister_media_entities`, `function camif_media_dev_init`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.