From mboxrd@z Thu Jan 1 00:00:00 1970 From: Shobhit Kumar Subject: [PATCH 6/8] drivers/pwm: Add Crystalcove (CRC) PWM driver Date: Wed, 29 Apr 2015 19:30:03 +0530 Message-ID: <1430316005-16480-7-git-send-email-shobhit.kumar@intel.com> References: <1430316005-16480-1-git-send-email-shobhit.kumar@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1430316005-16480-1-git-send-email-shobhit.kumar@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: intel-gfx , linux-kernel , linux-gpio , linux-pwm , dri-devel Cc: Alexandre Courbot , Samuel Ortiz , Povilas Staniulis , David Airlie , Shobhit Kumar , Linus Walleij , Jani Nikula , Chih-Wei Huang , Thierry Reding , Daniel Vetter , Lee Jones List-Id: linux-gpio@vger.kernel.org VGhlIENyeXN0YWxjb3ZlIFBNSUMgY29udHJvbHMgUFdNIHNpZ25hbHMgYW5kIHRoaXMgZHJpdmVy IGV4cG9ydHMgdGhhdApjYXBhYmlsaXR5IGFzIGEgUFdNIGNoaXAgZHJpdmVyLiBUaGlzIGlzIHBs YXRmb3JtIGRldmljZSBpbXBsZW1lbnR0YWlvbgpvZiB0aGUgZHJpdmVycy9tZmQgY2VsbCBkZXZp Y2UgZm9yIENSQyBQTUlDCgp2MjogVXNlIHRoZSBleGlzdGluZyBjb25maWcgY2FsbGJhY2sgd2l0 aCBkdXR5X25zIGFuZCBwZXJpb2RfbnMoVGhpZXJyeSkKCkNDOiBTYW11ZWwgT3J0aXogPHNhbWVv QGxpbnV4LmludGVsLmNvbT4KQ2M6IExpbnVzIFdhbGxlaWogPGxpbnVzLndhbGxlaWpAbGluYXJv Lm9yZz4KQ2M6IEFsZXhhbmRyZSBDb3VyYm90IDxnbnVyb3VAZ21haWwuY29tPgpDYzogVGhpZXJy eSBSZWRpbmcgPHRoaWVycnkucmVkaW5nQGdtYWlsLmNvbT4KU2lnbmVkLW9mZi1ieTogU2hvYmhp dCBLdW1hciA8c2hvYmhpdC5rdW1hckBpbnRlbC5jb20+Ci0tLQogZHJpdmVycy9wd20vS2NvbmZp ZyAgIHwgICA3ICsrKwogZHJpdmVycy9wd20vTWFrZWZpbGUgIHwgICAxICsKIGRyaXZlcnMvcHdt L3B3bS1jcmMuYyB8IDE3MSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKwogMyBmaWxlcyBjaGFuZ2VkLCAxNzkgaW5zZXJ0aW9ucygrKQogY3JlYXRlIG1v ZGUgMTAwNjQ0IGRyaXZlcnMvcHdtL3B3bS1jcmMuYwoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvcHdt L0tjb25maWcgYi9kcml2ZXJzL3B3bS9LY29uZmlnCmluZGV4IGIxNTQxZjQuLjk1NGRhM2UgMTAw NjQ0Ci0tLSBhL2RyaXZlcnMvcHdtL0tjb25maWcKKysrIGIvZHJpdmVycy9wd20vS2NvbmZpZwpA QCAtMTgzLDYgKzE4MywxMyBAQCBjb25maWcgUFdNX0xQQzMyWFgKIAkgIFRvIGNvbXBpbGUgdGhp cyBkcml2ZXIgYXMgYSBtb2R1bGUsIGNob29zZSBNIGhlcmU6IHRoZSBtb2R1bGUKIAkgIHdpbGwg YmUgY2FsbGVkIHB3bS1scGMzMnh4LgogCitjb25maWcgUFdNX0NSQworCWJvb2wgIkludGVsIENy eXN0YWxjb3ZlIChDUkMpIFBXTSBzdXBwb3J0IgorCWRlcGVuZHMgb24gWDg2ICYmIElOVEVMX1NP Q19QTUlDCisJaGVscAorCSAgR2VuZXJpYyBQV00gZnJhbWV3b3JrIGRyaXZlciBmb3IgQ3J5c3Rh bGNvdmUgKENSQykgUE1JQyBiYXNlZCBQV00KKwkgIGNvbnRyb2wuCisKIGNvbmZpZyBQV01fTFBT UwogCXRyaXN0YXRlICJJbnRlbCBMUFNTIFBXTSBzdXBwb3J0IgogCWRlcGVuZHMgb24gWDg2CmRp ZmYgLS1naXQgYS9kcml2ZXJzL3B3bS9NYWtlZmlsZSBiL2RyaXZlcnMvcHdtL01ha2VmaWxlCmlu ZGV4IGVjNTBlYjUuLjNkMzhmZWQgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvcHdtL01ha2VmaWxlCisr KyBiL2RyaXZlcnMvcHdtL01ha2VmaWxlCkBAIC0zNSwzICszNSw0IEBAIG9iai0kKENPTkZJR19Q V01fVElQV01TUykJKz0gcHdtLXRpcHdtc3Mubwogb2JqLSQoQ09ORklHX1BXTV9UV0wpCQkrPSBw d20tdHdsLm8KIG9iai0kKENPTkZJR19QV01fVFdMX0xFRCkJKz0gcHdtLXR3bC1sZWQubwogb2Jq LSQoQ09ORklHX1BXTV9WVDg1MDApCSs9IHB3bS12dDg1MDAubworb2JqLSQoQ09ORklHX1BXTV9D UkMpCQkrPSBwd20tY3JjLm8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvcHdtL3B3bS1jcmMuYyBiL2Ry aXZlcnMvcHdtL3B3bS1jcmMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45 ODdmM2I0Ci0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9wd20vcHdtLWNyYy5jCkBAIC0wLDAg KzEsMTcxIEBACisvKgorICogcHdtLWNyYy5jIC0gSW50ZWwgQ3J5c3RhbCBDb3ZlIFBXTSBEcml2 ZXIKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMTUgSW50ZWwgQ29ycG9yYXRpb24uIEFsbCByaWdo dHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBj YW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBv ZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgorICogMiBhcyBwdWJsaXNo ZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KKyAqCisgKiBUaGlzIHByb2dyYW0g aXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1 dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5 IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBP U0UuICBTZWUgdGhlCisgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRh aWxzLgorICoKKyAqIEF1dGhvcjogU2hvYmhpdCBLdW1hciA8c2hvYmhpdC5rdW1hckBpbnRlbC5j b20+CisgKi8KKworI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgorI2luY2x1ZGUgPGxpbnV4L3Bs YXRmb3JtX2RldmljZS5oPgorI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPgorI2luY2x1ZGUgPGxp bnV4L21mZC9pbnRlbF9zb2NfcG1pYy5oPgorI2luY2x1ZGUgPGxpbnV4L3B3bS5oPgorCisjZGVm aW5lIFBXTTBfQ0xLX0RJVgkJMHg0QgorI2RlZmluZSAgUFdNX09VVFBVVF9FTkFCTEUJKDE8PDcp CisjZGVmaW5lICBQV01fRElWX0NMS18wCQkweDAwIC8qIERJVklERUNMSyA9IEJBU0VDTEsgKi8K KyNkZWZpbmUgIFBXTV9ESVZfQ0xLXzEwMAkweDYzIC8qIERJVklERUNMSyA9IEJBU0VDTEsvMTAw ICovCisjZGVmaW5lICBQV01fRElWX0NMS18xMjgJMHg3RiAvKiBESVZJREVDTEsgPSBCQVNFQ0xL LzEyOCAqLworCisjZGVmaW5lIFBXTTBfRFVUWV9DWUNMRQkJMHg0RQorI2RlZmluZSBCQUNLTElH SFRfRU4JCTB4NTEKKworI2RlZmluZSBQV01fTUFYX0xFVkVMCQkweEZGCisKKyNkZWZpbmUgUFdN X0JBU0VfQ0xLCQk2MDAwCS8qIDYgTUh6ICovCisjZGVmaW5lIFBXTV9NQVhfUEVSSU9EX05TCTIx MzMzIC8qIDQ2Ljg3NUtIeiAqLworCisvKioKKyAqIHN0cnVjdCBjcnlzdGFsY292ZV9wd20gLSBD cnlzdGFsIENvdmUgUFdNIGNvbnRyb2xsZXIKKyAqIEBjaGlwOiB0aGUgYWJzdHJhY3QgcHdtX2No aXAgc3RydWN0dXJlLgorICogQHJlZ21hcDogdGhlIHJlZ21hcCBmcm9tIHRoZSBwYXJlbnQgZGV2 aWNlLgorICovCitzdHJ1Y3QgY3J5c3RhbGNvdmVfcHdtIHsKKwlzdHJ1Y3QgcHdtX2NoaXAgY2hp cDsKKwlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2OworCXN0cnVjdCByZWdtYXAgKnJlZ21h cDsKK307CisKK3N0YXRpYyBpbmxpbmUgc3RydWN0IGNyeXN0YWxjb3ZlX3B3bSAqdG9fY3JjX3B3 bShzdHJ1Y3QgcHdtX2NoaXAgKnBjKQoreworCXJldHVybiBjb250YWluZXJfb2YocGMsIHN0cnVj dCBjcnlzdGFsY292ZV9wd20sIGNoaXApOworfQorCitzdGF0aWMgaW50IGNyY19wd21fZW5hYmxl KHN0cnVjdCBwd21fY2hpcCAqYywgc3RydWN0IHB3bV9kZXZpY2UgKnB3bSkKK3sKKwlzdHJ1Y3Qg Y3J5c3RhbGNvdmVfcHdtICpjcmNfcHdtID0gdG9fY3JjX3B3bShjKTsKKworCXJlZ21hcF93cml0 ZShjcmNfcHdtLT5yZWdtYXAsIEJBQ0tMSUdIVF9FTiwgMSk7CisKKwlyZXR1cm4gMDsKK30KKwor c3RhdGljIHZvaWQgY3JjX3B3bV9kaXNhYmxlKHN0cnVjdCBwd21fY2hpcCAqYywgc3RydWN0IHB3 bV9kZXZpY2UgKnB3bSkKK3sKKwlzdHJ1Y3QgY3J5c3RhbGNvdmVfcHdtICpjcmNfcHdtID0gdG9f Y3JjX3B3bShjKTsKKworCXJlZ21hcF93cml0ZShjcmNfcHdtLT5yZWdtYXAsIEJBQ0tMSUdIVF9F TiwgMCk7Cit9CisKK3N0YXRpYyBpbnQgY3JjX3B3bV9jb25maWcoc3RydWN0IHB3bV9jaGlwICpj LCBzdHJ1Y3QgcHdtX2RldmljZSAqcHdtLAorCQkJCSAgaW50IGR1dHlfbnMsIGludCBwZXJpb2Rf bnMpCit7CisJc3RydWN0IGNyeXN0YWxjb3ZlX3B3bSAqY3JjX3B3bSA9IHRvX2NyY19wd20oYyk7 CisJc3RydWN0IGRldmljZSAqZGV2ID0gJmNyY19wd20tPnBkZXYtPmRldjsKKwlpbnQgbGV2ZWws IHBlcmNlbnQ7CisKKwlpZiAocGVyaW9kX25zID4gUFdNX01BWF9QRVJJT0RfTlMpIHsKKwkJZGV2 X2VycihkZXYsICJ1bi1zdXBwb3J0ZWQgcGVyaW9kX25zXG4iKTsKKwkJcmV0dXJuIC0xOworCX0K KworCWlmIChwd20tPnBlcmlvZCAhPSBwZXJpb2RfbnMpIHsKKwkJaW50IGNsa19kaXY7CisKKwkJ LyogY2hhbmdpbmcgdGhlIGNsayBkaXZpc29yLCBuZWVkIHRvIGRpc2FibGUgZmlzcnQgKi8KKwkJ Y3JjX3B3bV9kaXNhYmxlKGMsIHB3bSk7CisJCWNsa19kaXYgPSBQV01fQkFTRV9DTEsgKiBwZXJp b2RfbnMgLyAxMDAwMDAwOworCisJCXJlZ21hcF93cml0ZShjcmNfcHdtLT5yZWdtYXAsIFBXTTBf Q0xLX0RJViwKKwkJCQkJY2xrX2RpdiB8IFBXTV9PVVRQVVRfRU5BQkxFKTsKKworCQkvKiBlbmFi bGUgYmFjayAqLworCQljcmNfcHdtX2VuYWJsZShjLCBwd20pOworCX0KKworCWlmIChkdXR5X25z ID4gcGVyaW9kX25zKSB7CisJCWRldl9lcnIoZGV2LCAiZHV0eSBjeWNsZSBjYW5ub3QgYmUgZ3Jl YXRlciB0aGFuIGN5Y2xlIHBlcmlvZFxuIik7CisJCXJldHVybiAtMTsKKwl9CisKKwkvKiBjaGFu Z2UgdGhlIHB3bSBkdXR5IGN5Y2xlICovCisJcGVyY2VudCA9IGR1dHlfbnMgKiAxMDAgLyBwZXJp b2RfbnM7CisJbGV2ZWwgPSBwZXJjZW50ICogUFdNX01BWF9MRVZFTCAvIDEwMDsKKwlyZWdtYXBf d3JpdGUoY3JjX3B3bS0+cmVnbWFwLCBQV00wX0RVVFlfQ1lDTEUsIGxldmVsKTsKKworCXJldHVy biAwOworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IHB3bV9vcHMgY3JjX3B3bV9vcHMgPSB7CisJ LmNvbmZpZyA9IGNyY19wd21fY29uZmlnLAorCS5lbmFibGUgPSBjcmNfcHdtX2VuYWJsZSwKKwku ZGlzYWJsZSA9IGNyY19wd21fZGlzYWJsZSwKKwkub3duZXIgPSBUSElTX01PRFVMRSwKK307CisK K3N0YXRpYyBpbnQgY3J5c3RhbGNvdmVfcHdtX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2Ug KnBkZXYpCit7CisJc3RydWN0IGNyeXN0YWxjb3ZlX3B3bSAqcHdtOworCWludCByZXR2YWw7CisJ c3RydWN0IGRldmljZSAqZGV2ID0gcGRldi0+ZGV2LnBhcmVudDsKKwlzdHJ1Y3QgaW50ZWxfc29j X3BtaWMgKnBtaWMgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKKworCXB3bSA9IGRldm1fa3phbGxv YygmcGRldi0+ZGV2LCBzaXplb2YoKnB3bSksIEdGUF9LRVJORUwpOworCWlmICghcHdtKQorCQly ZXR1cm4gLUVOT01FTTsKKworCXB3bS0+Y2hpcC5kZXYgPSAmcGRldi0+ZGV2OworCXB3bS0+Y2hp cC5vcHMgPSAmY3JjX3B3bV9vcHM7CisJcHdtLT5jaGlwLmJhc2UgPSAtMTsKKwlwd20tPmNoaXAu bnB3bSA9IDE7CisKKwkvKiBnZXQgdGhlIFBNSUMgcmVnbWFwICovCisJcHdtLT5yZWdtYXAgPSBw bWljLT5yZWdtYXA7CisKKwlyZXR2YWwgPSBwd21jaGlwX2FkZCgmcHdtLT5jaGlwKTsKKwlpZiAo cmV0dmFsIDwgMCkKKwkJcmV0dXJuIHJldHZhbDsKKworCWRldl9kYmcoJnBkZXYtPmRldiwgImNy Yy1wd20gcHJvYmUgc3VjY2Vzc2Z1bFxuIik7CisJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwg cHdtKTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGNyeXN0YWxjb3ZlX3B3bV9yZW1v dmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKK3sKKwlzdHJ1Y3QgY3J5c3RhbGNvdmVf cHdtICpwd20gPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKKwlpbnQgcmV0dmFsOworCisJ cmV0dmFsID0gcHdtY2hpcF9yZW1vdmUoJnB3bS0+Y2hpcCk7CisJaWYgKHJldHZhbCA8IDApCisJ CXJldHVybiByZXR2YWw7CisKKwlkZXZfZGJnKCZwZGV2LT5kZXYsICJjcmMtcHdtIGRyaXZlciBy ZW1vdmVkXG4iKTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2Ry aXZlciBjcnlzdGFsY292ZV9wd21fZHJpdmVyID0geworCS5wcm9iZSA9IGNyeXN0YWxjb3ZlX3B3 bV9wcm9iZSwKKwkucmVtb3ZlID0gY3J5c3RhbGNvdmVfcHdtX3JlbW92ZSwKKwkuZHJpdmVyID0g eworCQkubmFtZSA9ICJjcnlzdGFsX2NvdmVfcHdtIiwKKwl9LAorfTsKKworbW9kdWxlX3BsYXRm b3JtX2RyaXZlcihjcnlzdGFsY292ZV9wd21fZHJpdmVyKTsKKworTU9EVUxFX0FVVEhPUigiU2hv YmhpdCBLdW1hciA8c2hvYmhpdC5rdW1hckBpbnRlbC5jb20+Iik7CitNT0RVTEVfREVTQ1JJUFRJ T04oIkludGVsIENyeXN0YWwgQ292ZSBQV00gRHJpdmVyIik7CitNT0RVTEVfTElDRU5TRSgiR1BM IHYyIik7Ci0tIAoyLjEuMAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KSW50ZWwtZ2Z4IG1haWxpbmcgbGlzdApJbnRlbC1nZnhAbGlzdHMuZnJlZWRlc2t0 b3Aub3JnCmh0dHA6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9pbnRl bC1nZngK From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966271AbbD2OBS (ORCPT ); Wed, 29 Apr 2015 10:01:18 -0400 Received: from mga09.intel.com ([134.134.136.24]:50266 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1423080AbbD2OBO (ORCPT ); Wed, 29 Apr 2015 10:01:14 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,671,1422950400"; d="scan'208";a="717791168" From: Shobhit Kumar To: intel-gfx , linux-kernel , linux-gpio , linux-pwm , dri-devel Cc: Linus Walleij , Alexandre Courbot , Daniel Vetter , David Airlie , Samuel Ortiz , Thierry Reding , Jani Nikula , Lee Jones , Povilas Staniulis , Chih-Wei Huang , Shobhit Kumar Subject: [PATCH 6/8] drivers/pwm: Add Crystalcove (CRC) PWM driver Date: Wed, 29 Apr 2015 19:30:03 +0530 Message-Id: <1430316005-16480-7-git-send-email-shobhit.kumar@intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1430316005-16480-1-git-send-email-shobhit.kumar@intel.com> References: <1430316005-16480-1-git-send-email-shobhit.kumar@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The Crystalcove PMIC controls PWM signals and this driver exports that capability as a PWM chip driver. This is platform device implementtaion of the drivers/mfd cell device for CRC PMIC v2: Use the existing config callback with duty_ns and period_ns(Thierry) CC: Samuel Ortiz Cc: Linus Walleij Cc: Alexandre Courbot Cc: Thierry Reding Signed-off-by: Shobhit Kumar --- drivers/pwm/Kconfig | 7 +++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-crc.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/pwm/pwm-crc.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index b1541f4..954da3e 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -183,6 +183,13 @@ config PWM_LPC32XX To compile this driver as a module, choose M here: the module will be called pwm-lpc32xx. +config PWM_CRC + bool "Intel Crystalcove (CRC) PWM support" + depends on X86 && INTEL_SOC_PMIC + help + Generic PWM framework driver for Crystalcove (CRC) PMIC based PWM + control. + config PWM_LPSS tristate "Intel LPSS PWM support" depends on X86 diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index ec50eb5..3d38fed 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -35,3 +35,4 @@ obj-$(CONFIG_PWM_TIPWMSS) += pwm-tipwmss.o obj-$(CONFIG_PWM_TWL) += pwm-twl.o obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o +obj-$(CONFIG_PWM_CRC) += pwm-crc.o diff --git a/drivers/pwm/pwm-crc.c b/drivers/pwm/pwm-crc.c new file mode 100644 index 0000000..987f3b4 --- /dev/null +++ b/drivers/pwm/pwm-crc.c @@ -0,0 +1,171 @@ +/* + * pwm-crc.c - Intel Crystal Cove PWM Driver + * + * Copyright (C) 2015 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. + * + * Author: Shobhit Kumar + */ + +#include +#include +#include +#include +#include + +#define PWM0_CLK_DIV 0x4B +#define PWM_OUTPUT_ENABLE (1<<7) +#define PWM_DIV_CLK_0 0x00 /* DIVIDECLK = BASECLK */ +#define PWM_DIV_CLK_100 0x63 /* DIVIDECLK = BASECLK/100 */ +#define PWM_DIV_CLK_128 0x7F /* DIVIDECLK = BASECLK/128 */ + +#define PWM0_DUTY_CYCLE 0x4E +#define BACKLIGHT_EN 0x51 + +#define PWM_MAX_LEVEL 0xFF + +#define PWM_BASE_CLK 6000 /* 6 MHz */ +#define PWM_MAX_PERIOD_NS 21333 /* 46.875KHz */ + +/** + * struct crystalcove_pwm - Crystal Cove PWM controller + * @chip: the abstract pwm_chip structure. + * @regmap: the regmap from the parent device. + */ +struct crystalcove_pwm { + struct pwm_chip chip; + struct platform_device *pdev; + struct regmap *regmap; +}; + +static inline struct crystalcove_pwm *to_crc_pwm(struct pwm_chip *pc) +{ + return container_of(pc, struct crystalcove_pwm, chip); +} + +static int crc_pwm_enable(struct pwm_chip *c, struct pwm_device *pwm) +{ + struct crystalcove_pwm *crc_pwm = to_crc_pwm(c); + + regmap_write(crc_pwm->regmap, BACKLIGHT_EN, 1); + + return 0; +} + +static void crc_pwm_disable(struct pwm_chip *c, struct pwm_device *pwm) +{ + struct crystalcove_pwm *crc_pwm = to_crc_pwm(c); + + regmap_write(crc_pwm->regmap, BACKLIGHT_EN, 0); +} + +static int crc_pwm_config(struct pwm_chip *c, struct pwm_device *pwm, + int duty_ns, int period_ns) +{ + struct crystalcove_pwm *crc_pwm = to_crc_pwm(c); + struct device *dev = &crc_pwm->pdev->dev; + int level, percent; + + if (period_ns > PWM_MAX_PERIOD_NS) { + dev_err(dev, "un-supported period_ns\n"); + return -1; + } + + if (pwm->period != period_ns) { + int clk_div; + + /* changing the clk divisor, need to disable fisrt */ + crc_pwm_disable(c, pwm); + clk_div = PWM_BASE_CLK * period_ns / 1000000; + + regmap_write(crc_pwm->regmap, PWM0_CLK_DIV, + clk_div | PWM_OUTPUT_ENABLE); + + /* enable back */ + crc_pwm_enable(c, pwm); + } + + if (duty_ns > period_ns) { + dev_err(dev, "duty cycle cannot be greater than cycle period\n"); + return -1; + } + + /* change the pwm duty cycle */ + percent = duty_ns * 100 / period_ns; + level = percent * PWM_MAX_LEVEL / 100; + regmap_write(crc_pwm->regmap, PWM0_DUTY_CYCLE, level); + + return 0; +} + +static const struct pwm_ops crc_pwm_ops = { + .config = crc_pwm_config, + .enable = crc_pwm_enable, + .disable = crc_pwm_disable, + .owner = THIS_MODULE, +}; + +static int crystalcove_pwm_probe(struct platform_device *pdev) +{ + struct crystalcove_pwm *pwm; + int retval; + struct device *dev = pdev->dev.parent; + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); + if (!pwm) + return -ENOMEM; + + pwm->chip.dev = &pdev->dev; + pwm->chip.ops = &crc_pwm_ops; + pwm->chip.base = -1; + pwm->chip.npwm = 1; + + /* get the PMIC regmap */ + pwm->regmap = pmic->regmap; + + retval = pwmchip_add(&pwm->chip); + if (retval < 0) + return retval; + + dev_dbg(&pdev->dev, "crc-pwm probe successful\n"); + platform_set_drvdata(pdev, pwm); + + return 0; +} + +static int crystalcove_pwm_remove(struct platform_device *pdev) +{ + struct crystalcove_pwm *pwm = platform_get_drvdata(pdev); + int retval; + + retval = pwmchip_remove(&pwm->chip); + if (retval < 0) + return retval; + + dev_dbg(&pdev->dev, "crc-pwm driver removed\n"); + + return 0; +} + +static struct platform_driver crystalcove_pwm_driver = { + .probe = crystalcove_pwm_probe, + .remove = crystalcove_pwm_remove, + .driver = { + .name = "crystal_cove_pwm", + }, +}; + +module_platform_driver(crystalcove_pwm_driver); + +MODULE_AUTHOR("Shobhit Kumar "); +MODULE_DESCRIPTION("Intel Crystal Cove PWM Driver"); +MODULE_LICENSE("GPL v2"); -- 2.1.0