cregit-Linux how code gets into the kernel

Release 4.7 drivers/media/platform/s5p-tv/mixer.h

/*
 * Samsung TV Mixer driver
 *
 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
 *
 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
 *
 * 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 Foundiation. either version 2 of the License,
 * or (at your option) any later version
 */

#ifndef SAMSUNG_MIXER_H

#define SAMSUNG_MIXER_H

#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
	
#define DEBUG
#endif

#include <linux/fb.h>
#include <linux/irqreturn.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <media/v4l2-device.h>
#include <media/videobuf2-v4l2.h>

#include "regs-mixer.h"

/** maximum number of output interfaces */

#define MXR_MAX_OUTPUTS 2
/** maximum number of input interfaces (layers) */

#define MXR_MAX_LAYERS 3

#define MXR_DRIVER_NAME "s5p-mixer"
/** maximal number of planes for every layer */

#define MXR_MAX_PLANES	2


#define MXR_ENABLE 1

#define MXR_DISABLE 0

/** description of a macroblock for packed formats */

struct mxr_block {
	/** vertical number of pixels in macroblock */
	
unsigned int width;
	/** horizontal number of pixels in macroblock */
	
unsigned int height;
	/** size of block in bytes */
	
unsigned int size;
};

/** description of supported format */

struct mxr_format {
	/** format name/mnemonic */
	
const char *name;
	/** fourcc identifier */
	
u32 fourcc;
	/** colorspace identifier */
	
enum v4l2_colorspace colorspace;
	/** number of planes in image data */
	
int num_planes;
	/** description of block for each plane */
	
struct mxr_block plane[MXR_MAX_PLANES];
	/** number of subframes in image data */
	
int num_subframes;
	/** specifies to which subframe belong given plane */
	
int plane2subframe[MXR_MAX_PLANES];
	/** internal code, driver dependent */
	
unsigned long cookie;
};

/** description of crop configuration for image */

struct mxr_crop {
	/** width of layer in pixels */
	
unsigned int full_width;
	/** height of layer in pixels */
	
unsigned int full_height;
	/** horizontal offset of first pixel to be displayed */
	
unsigned int x_offset;
	/** vertical offset of first pixel to be displayed */
	
unsigned int y_offset;
	/** width of displayed data in pixels */
	
unsigned int width;
	/** height of displayed data in pixels */
	
unsigned int height;
	/** indicate which fields are present in buffer */
	
unsigned int field;
};

/** stages of geometry operations */

enum mxr_geometry_stage {
	
MXR_GEOMETRY_SINK,
	
MXR_GEOMETRY_COMPOSE,
	
MXR_GEOMETRY_CROP,
	
MXR_GEOMETRY_SOURCE,
};

/* flag indicating that offset should be 0 */

#define MXR_NO_OFFSET	0x80000000

/** description of transformation from source to destination image */

struct mxr_geometry {
	/** cropping for source image */
	
struct mxr_crop src;
	/** cropping for destination image */
	
struct mxr_crop dst;
	/** layer-dependant description of horizontal scaling */
	
unsigned int x_ratio;
	/** layer-dependant description of vertical scaling */
	
unsigned int y_ratio;
};

/** instance of a buffer */

struct mxr_buffer {
	/** common v4l buffer stuff -- must be first */
	
struct vb2_v4l2_buffer vb;
	/** node for layer's lists */
	
struct list_head	list;
};


/** internal states of layer */

enum mxr_layer_state {
	/** layers is not shown */
	
MXR_LAYER_IDLE = 0,
	/** layer is shown */
	
MXR_LAYER_STREAMING,
	/** state before STREAMOFF is finished */
	
MXR_LAYER_STREAMING_FINISH,
};

/** forward declarations */
struct mxr_device;
struct mxr_layer;

/** callback for layers operation */

struct mxr_layer_ops {
	/* TODO: try to port it to subdev API */
	/** handler for resource release function */
	
void (*release)(struct mxr_layer *);
	/** setting buffer to HW */
	
void (*buffer_set)(struct mxr_layer *, struct mxr_buffer *);
	/** setting format and geometry in HW */
	
void (*format_set)(struct mxr_layer *);
	/** streaming stop/start */
	
void (*stream_set)(struct mxr_layer *, int);
	/** adjusting geometry */
	
void (*fix_geometry)(struct mxr_layer *,
		enum mxr_geometry_stage, unsigned long);
};

/** layer instance, a single window and content displayed on output */

struct mxr_layer {
	/** parent mixer device */
	
struct mxr_device *mdev;
	/** layer index (unique identifier) */
	
int idx;
	/** callbacks for layer methods */
	
struct mxr_layer_ops ops;
	/** format array */
	
const struct mxr_format **fmt_array;
	/** size of format array */
	
unsigned long fmt_array_size;

	/** lock for protection of list and state fields */
	
spinlock_t enq_slock;
	/** list for enqueued buffers */
	
struct list_head enq_list;
	/** buffer currently owned by hardware in temporary registers */
	
struct mxr_buffer *update_buf;
	/** buffer currently owned by hardware in shadow registers */
	
struct mxr_buffer *shadow_buf;
	/** state of layer IDLE/STREAMING */
	
enum mxr_layer_state state;

	/** mutex for protection of fields below */
	
struct mutex mutex;
	/** handler for video node */
	
struct video_device vfd;
	/** queue for output buffers */
	
struct vb2_queue vb_queue;
	/** current image format */
	
const struct mxr_format *fmt;
	/** current geometry of image */
	
struct mxr_geometry geo;
};

/** description of mixers output interface */

struct mxr_output {
	/** name of output */
	
char name[32];
	/** output subdev */
	
struct v4l2_subdev *sd;
	/** cookie used for configuration of registers */
	
int cookie;
};

/** specify source of output subdevs */

struct mxr_output_conf {
	/** name of output (connector) */
	
char *output_name;
	/** name of module that generates output subdev */
	
char *module_name;
	/** cookie need for mixer HW */
	
int cookie;
};

struct clk;
struct regulator;

/** auxiliary resources used my mixer */

struct mxr_resources {
	/** interrupt index */
	
int irq;
	/** pointer to Mixer registers */
	
void __iomem *mxr_regs;
	/** pointer to Video Processor registers */
	
void __iomem *vp_regs;
	/** other resources, should used under mxr_device.mutex */
	
struct clk *mixer;
	
struct clk *vp;
	
struct clk *sclk_mixer;
	
struct clk *sclk_hdmi;
	
struct clk *sclk_dac;
};

/* event flags used  */

enum mxr_devide_flags {
	
MXR_EVENT_VSYNC = 0,
	
MXR_EVENT_TOP = 1,
};

/** drivers instance */

struct mxr_device {
	/** master device */
	
struct device *dev;
	/** state of each layer */
	
struct mxr_layer *layer[MXR_MAX_LAYERS];
	/** state of each output */
	
struct mxr_output *output[MXR_MAX_OUTPUTS];
	/** number of registered outputs */
	
int output_cnt;

	/* video resources */

	/** V4L2 device */
	
struct v4l2_device v4l2_dev;
	/** context of allocator */
	
void *alloc_ctx;
	/** event wait queue */
	
wait_queue_head_t event_queue;
	/** state flags */
	
unsigned long event_flags;

	/** spinlock for protection of registers */
	
spinlock_t reg_slock;

	/** mutex for protection of fields below */
	
struct mutex mutex;
	/** number of entities depndant on output configuration */
	
int n_output;
	/** number of users that do streaming */
	
int n_streamer;
	/** index of current output */
	
int current_output;
	/** auxiliary resources used my mixer */
	
struct mxr_resources res;
};

/** transform device structure into mixer device */

static inline struct mxr_device *to_mdev(struct device *dev) { struct v4l2_device *vdev = dev_get_drvdata(dev); return container_of(vdev, struct mxr_device, v4l2_dev); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski35100.00%1100.00%
Total35100.00%1100.00%

/** get current output data, should be called under mdev's mutex */
static inline struct mxr_output *to_output(struct mxr_device *mdev) { return mdev->output[mdev->current_output]; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski24100.00%1100.00%
Total24100.00%1100.00%

/** get current output subdev, should be called under mdev's mutex */
static inline struct v4l2_subdev *to_outsd(struct mxr_device *mdev) { struct mxr_output *out = to_output(mdev); return out ? out->sd : NULL; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski33100.00%1100.00%
Total33100.00%1100.00%

/** forward declaration for mixer platform data */ struct mxr_platform_data; /** acquiring common video resources */ int mxr_acquire_video(struct mxr_device *mdev, struct mxr_output_conf *output_cont, int output_count); /** releasing common video resources */ void mxr_release_video(struct mxr_device *mdev); struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx); struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx); struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev, int idx, char *name, const struct mxr_layer_ops *ops); void mxr_base_layer_release(struct mxr_layer *layer); void mxr_layer_release(struct mxr_layer *layer); int mxr_base_layer_register(struct mxr_layer *layer); void mxr_base_layer_unregister(struct mxr_layer *layer); unsigned long mxr_get_plane_size(const struct mxr_block *blk, unsigned int width, unsigned int height); /** adds new consumer for mixer's power */ int __must_check mxr_power_get(struct mxr_device *mdev); /** removes consumer for mixer's power */ void mxr_power_put(struct mxr_device *mdev); /** add new client for output configuration */ void mxr_output_get(struct mxr_device *mdev); /** removes new client for output configuration */ void mxr_output_put(struct mxr_device *mdev); /** add new client for streaming */ void mxr_streamer_get(struct mxr_device *mdev); /** removes new client for streaming */ void mxr_streamer_put(struct mxr_device *mdev); /** returns format of data delivared to current output */ void mxr_get_mbus_fmt(struct mxr_device *mdev, struct v4l2_mbus_framefmt *mbus_fmt); /* Debug */ #define mxr_err(mdev, fmt, ...) dev_err(mdev->dev, fmt, ##__VA_ARGS__) #define mxr_warn(mdev, fmt, ...) dev_warn(mdev->dev, fmt, ##__VA_ARGS__) #define mxr_info(mdev, fmt, ...) dev_info(mdev->dev, fmt, ##__VA_ARGS__) #ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG #define mxr_dbg(mdev, fmt, ...) dev_dbg(mdev->dev, fmt, ##__VA_ARGS__) #else #define mxr_dbg(mdev, fmt, ...) do { (void) mdev; } while (0) #endif /* accessing Mixer's and Video Processor's registers */ void mxr_vsync_set_update(struct mxr_device *mdev, int en); void mxr_reg_reset(struct mxr_device *mdev); irqreturn_t mxr_irq_handler(int irq, void *dev_data); void mxr_reg_s_output(struct mxr_device *mdev, int cookie); void mxr_reg_streamon(struct mxr_device *mdev); void mxr_reg_streamoff(struct mxr_device *mdev); int mxr_reg_wait4vsync(struct mxr_device *mdev); void mxr_reg_set_mbus_fmt(struct mxr_device *mdev, struct v4l2_mbus_framefmt *fmt); void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en); void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr); void mxr_reg_graph_format(struct mxr_device *mdev, int idx, const struct mxr_format *fmt, const struct mxr_geometry *geo); void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en); void mxr_reg_vp_buffer(struct mxr_device *mdev, dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2]); void mxr_reg_vp_format(struct mxr_device *mdev, const struct mxr_format *fmt, const struct mxr_geometry *geo); void mxr_reg_dump(struct mxr_device *mdev); #endif /* SAMSUNG_MIXER_H */

Overall Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski118899.41%337.50%
sachin kamatsachin kamat30.25%112.50%
junghak sungjunghak sung20.17%225.00%
julia lawalljulia lawall10.08%112.50%
jonathan mccrohanjonathan mccrohan10.08%112.50%
Total1195100.00%8100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}