cregit-Linux how code gets into the kernel

Release 4.11 drivers/gpu/drm/mediatek/mtk_cec.c

/*
 * Copyright (c) 2014 MediaTek Inc.
 * Author: Jie Qiu <jie.qiu@mediatek.com>
 *
 * 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 <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>

#include "mtk_cec.h"


#define TR_CONFIG		0x00

#define CLEAR_CEC_IRQ			BIT(15)


#define CEC_CKGEN		0x04

#define CEC_32K_PDN			BIT(19)

#define PDN				BIT(16)


#define RX_EVENT		0x54

#define HDMI_PORD			BIT(25)

#define HDMI_HTPLG			BIT(24)

#define HDMI_PORD_INT_EN		BIT(9)

#define HDMI_HTPLG_INT_EN		BIT(8)


#define RX_GEN_WD		0x58

#define HDMI_PORD_INT_32K_STATUS	BIT(26)

#define RX_RISC_INT_32K_STATUS		BIT(25)

#define HDMI_HTPLG_INT_32K_STATUS	BIT(24)

#define HDMI_PORD_INT_32K_CLR		BIT(18)

#define RX_INT_32K_CLR			BIT(17)

#define HDMI_HTPLG_INT_32K_CLR		BIT(16)

#define HDMI_PORD_INT_32K_STA_MASK	BIT(10)

#define RX_RISC_INT_32K_STA_MASK	BIT(9)

#define HDMI_HTPLG_INT_32K_STA_MASK	BIT(8)

#define HDMI_PORD_INT_32K_EN		BIT(2)

#define RX_INT_32K_EN			BIT(1)

#define HDMI_HTPLG_INT_32K_EN		BIT(0)


#define NORMAL_INT_CTRL		0x5C

#define HDMI_HTPLG_INT_STA		BIT(0)

#define HDMI_PORD_INT_STA		BIT(1)

#define HDMI_HTPLG_INT_CLR		BIT(16)

#define HDMI_PORD_INT_CLR		BIT(17)

#define HDMI_FULL_INT_CLR		BIT(20)


struct mtk_cec {
	
void __iomem *regs;
	
struct clk *clk;
	
int irq;
	
bool hpd;
	
void (*hpd_event)(bool hpd, struct device *dev);
	
struct device *hdmi_dev;
	
spinlock_t lock;
};


static void mtk_cec_clear_bits(struct mtk_cec *cec, unsigned int offset, unsigned int bits) { void __iomem *reg = cec->regs + offset; u32 tmp; tmp = readl(reg); tmp &= ~bits; writel(tmp, reg); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu52100.00%1100.00%
Total52100.00%1100.00%


static void mtk_cec_set_bits(struct mtk_cec *cec, unsigned int offset, unsigned int bits) { void __iomem *reg = cec->regs + offset; u32 tmp; tmp = readl(reg); tmp |= bits; writel(tmp, reg); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu51100.00%1100.00%
Total51100.00%1100.00%


static void mtk_cec_mask(struct mtk_cec *cec, unsigned int offset, unsigned int val, unsigned int mask) { u32 tmp = readl(cec->regs + offset) & ~mask; tmp |= val & mask; writel(val, cec->regs + offset); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu55100.00%1100.00%
Total55100.00%1100.00%


void mtk_cec_set_hpd_event(struct device *dev, void (*hpd_event)(bool hpd, struct device *dev), struct device *hdmi_dev) { struct mtk_cec *cec = dev_get_drvdata(dev); unsigned long flags; spin_lock_irqsave(&cec->lock, flags); cec->hdmi_dev = hdmi_dev; cec->hpd_event = hpd_event; spin_unlock_irqrestore(&cec->lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu76100.00%1100.00%
Total76100.00%1100.00%


bool mtk_cec_hpd_high(struct device *dev) { struct mtk_cec *cec = dev_get_drvdata(dev); unsigned int status; status = readl(cec->regs + RX_EVENT); return (status & (HDMI_PORD | HDMI_HTPLG)) == (HDMI_PORD | HDMI_HTPLG); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu52100.00%1100.00%
Total52100.00%1100.00%


static void mtk_cec_htplg_irq_init(struct mtk_cec *cec) { mtk_cec_mask(cec, CEC_CKGEN, 0 | CEC_32K_PDN, PDN | CEC_32K_PDN); mtk_cec_set_bits(cec, RX_GEN_WD, HDMI_PORD_INT_32K_CLR | RX_INT_32K_CLR | HDMI_HTPLG_INT_32K_CLR); mtk_cec_mask(cec, RX_GEN_WD, 0, HDMI_PORD_INT_32K_CLR | RX_INT_32K_CLR | HDMI_HTPLG_INT_32K_CLR | HDMI_PORD_INT_32K_EN | RX_INT_32K_EN | HDMI_HTPLG_INT_32K_EN); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu60100.00%1100.00%
Total60100.00%1100.00%


static void mtk_cec_htplg_irq_enable(struct mtk_cec *cec) { mtk_cec_set_bits(cec, RX_EVENT, HDMI_PORD_INT_EN | HDMI_HTPLG_INT_EN); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu22100.00%1100.00%
Total22100.00%1100.00%


static void mtk_cec_htplg_irq_disable(struct mtk_cec *cec) { mtk_cec_clear_bits(cec, RX_EVENT, HDMI_PORD_INT_EN | HDMI_HTPLG_INT_EN); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu22100.00%1100.00%
Total22100.00%1100.00%


static void mtk_cec_clear_htplg_irq(struct mtk_cec *cec) { mtk_cec_set_bits(cec, TR_CONFIG, CLEAR_CEC_IRQ); mtk_cec_set_bits(cec, NORMAL_INT_CTRL, HDMI_HTPLG_INT_CLR | HDMI_PORD_INT_CLR | HDMI_FULL_INT_CLR); mtk_cec_set_bits(cec, RX_GEN_WD, HDMI_PORD_INT_32K_CLR | RX_INT_32K_CLR | HDMI_HTPLG_INT_32K_CLR); usleep_range(5, 10); mtk_cec_clear_bits(cec, NORMAL_INT_CTRL, HDMI_HTPLG_INT_CLR | HDMI_PORD_INT_CLR | HDMI_FULL_INT_CLR); mtk_cec_clear_bits(cec, TR_CONFIG, CLEAR_CEC_IRQ); mtk_cec_clear_bits(cec, RX_GEN_WD, HDMI_PORD_INT_32K_CLR | RX_INT_32K_CLR | HDMI_HTPLG_INT_32K_CLR); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu88100.00%1100.00%
Total88100.00%1100.00%


static void mtk_cec_hpd_event(struct mtk_cec *cec, bool hpd) { void (*hpd_event)(bool hpd, struct device *dev); struct device *hdmi_dev; unsigned long flags; spin_lock_irqsave(&cec->lock, flags); hpd_event = cec->hpd_event; hdmi_dev = cec->hdmi_dev; spin_unlock_irqrestore(&cec->lock, flags); if (hpd_event) hpd_event(hpd, hdmi_dev); }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu81100.00%1100.00%
Total81100.00%1100.00%


static irqreturn_t mtk_cec_htplg_isr_thread(int irq, void *arg) { struct device *dev = arg; struct mtk_cec *cec = dev_get_drvdata(dev); bool hpd; mtk_cec_clear_htplg_irq(cec); hpd = mtk_cec_hpd_high(dev); if (cec->hpd != hpd) { dev_dbg(dev, "hotplug event! cur hpd = %d, hpd = %d\n", cec->hpd, hpd); cec->hpd = hpd; mtk_cec_hpd_event(cec, hpd); } return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu84100.00%1100.00%
Total84100.00%1100.00%


static int mtk_cec_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct mtk_cec *cec; struct resource *res; int ret; cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL); if (!cec) return -ENOMEM; platform_set_drvdata(pdev, cec); spin_lock_init(&cec->lock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); cec->regs = devm_ioremap_resource(dev, res); if (IS_ERR(cec->regs)) { ret = PTR_ERR(cec->regs); dev_err(dev, "Failed to ioremap cec: %d\n", ret); return ret; } cec->clk = devm_clk_get(dev, NULL); if (IS_ERR(cec->clk)) { ret = PTR_ERR(cec->clk); dev_err(dev, "Failed to get cec clock: %d\n", ret); return ret; } cec->irq = platform_get_irq(pdev, 0); if (cec->irq < 0) { dev_err(dev, "Failed to get cec irq: %d\n", cec->irq); return cec->irq; } ret = devm_request_threaded_irq(dev, cec->irq, NULL, mtk_cec_htplg_isr_thread, IRQF_SHARED | IRQF_TRIGGER_LOW | IRQF_ONESHOT, "hdmi hpd", dev); if (ret) { dev_err(dev, "Failed to register cec irq: %d\n", ret); return ret; } ret = clk_prepare_enable(cec->clk); if (ret) { dev_err(dev, "Failed to enable cec clock: %d\n", ret); return ret; } mtk_cec_htplg_irq_init(cec); mtk_cec_htplg_irq_enable(cec); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu290100.00%1100.00%
Total290100.00%1100.00%


static int mtk_cec_remove(struct platform_device *pdev) { struct mtk_cec *cec = platform_get_drvdata(pdev); mtk_cec_htplg_irq_disable(cec); clk_disable_unprepare(cec->clk); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu36100.00%1100.00%
Total36100.00%1100.00%

static const struct of_device_id mtk_cec_of_ids[] = { { .compatible = "mediatek,mt8173-cec", }, {} }; struct platform_driver mtk_cec_driver = { .probe = mtk_cec_probe, .remove = mtk_cec_remove, .driver = { .name = "mediatek-cec", .of_match_table = mtk_cec_of_ids, }, };

Overall Contributors

PersonTokensPropCommitsCommitProp
Jie Qiu1197100.00%1100.00%
Total1197100.00%1100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.