Index: git/drivers/media/video/isp/bluegamma_table.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ git/drivers/media/video/isp/bluegamma_table.h 2009-02-12 10:29:26.000000000 -0600 @@ -0,0 +1,1040 @@ +/* + * drivers/media/video/omap/isp/redgamma_table.h + * + * Gamma Table values for Red for TI's OMAP3430 Camera ISP + * + * Copyright (C) 2007 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +0, +0, +1, +2, +3, +3, +4, +5, +6, +8, +10, +12, +14, +16, +18, +20, +22, +23, +25, +26, +28, +29, +31, +32, +34, +35, +36, +37, +39, +40, +41, +42, +43, +44, +45, +46, +47, +48, +49, +50, +51, +52, +52, +53, +54, +55, +56, +57, +58, +59, +60, +61, +62, +63, +63, +64, +65, +66, +66, +67, +68, +69, +69, +70, +71, +72, +72, +73, +74, +75, +75, +76, +77, +78, +78, +79, +80, +81, +81, +82, +83, +84, +84, +85, +86, +87, +88, +88, +89, +90, +91, +91, +92, +93, +94, +94, +95, +96, +97, +97, +98, +98, +99, +99, +100, +100, +101, +101, +102, +103, +104, +104, +105, +106, +107, +108, +108, +109, +110, +111, +111, +112, +113, +114, +114, +115, +116, +117, +117, +118, +119, +119, +120, +120, +121, +121, +122, +122, +123, +123, +124, +124, +125, +125, +126, +126, +127, +127, +128, +128, +129, +129, +130, +130, +131, +131, +132, +132, +133, +133, +134, +134, +135, +135, +136, +136, +137, +137, +138, +138, +139, +139, +140, +140, +141, +141, +142, +142, +143, +143, +144, +144, +145, +145, +146, +146, +147, +147, +148, +148, +149, +149, +150, +150, +151, +151, +152, +152, +153, +153, +153, +153, +154, +154, +154, +154, +155, +155, +156, +156, +157, +157, +158, +158, +158, +159, +159, +159, +160, +160, +160, +161, +161, +162, +162, +163, +163, +164, +164, +164, +164, +165, +165, +165, +165, +166, +166, +167, +167, +168, +168, +169, +169, +170, +170, +170, +170, +171, +171, +171, +171, +172, +172, +173, +173, +174, +174, +175, +175, +176, +176, +176, +176, +177, +177, +177, +177, +178, +178, +178, +178, +179, +179, +179, +179, +180, +180, +180, +180, +181, +181, +181, +181, +182, +182, +182, +182, +183, +183, +183, +183, +184, +184, +184, +184, +185, +185, +185, +185, +186, +186, +186, +186, +187, +187, +187, +187, +188, +188, +188, +188, +189, +189, +189, +189, +190, +190, +190, +190, +191, +191, +191, +191, +192, +192, +192, +192, +193, +193, +193, +193, +194, +194, +194, +194, +195, +195, +195, +195, +196, +196, +196, +196, +197, +197, +197, +197, +198, +198, +198, +198, +199, +199, +199, +199, +200, +200, +200, +200, +201, +201, +201, +201, +202, +202, +202, +203, +203, +203, +203, +204, +204, +204, +204, +205, +205, +205, +205, +206, +206, +206, +206, +207, +207, +207, +207, +208, +208, +208, +208, +209, +209, +209, +209, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +211, +211, +211, +211, +211, +211, +211, +211, +211, +211, +211, +212, +212, +212, +212, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +214, +214, +214, +214, +215, +215, +215, +215, +215, +215, +215, +215, +215, +215, +215, +216, +216, +216, +216, +217, +217, +217, +217, +218, +218, +218, +218, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +220, +220, +220, +220, +221, +221, +221, +221, +221, +221, +221, +221, +221, +221, +221, +222, +222, +222, +222, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +224, +224, +224, +224, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +226, +226, +226, +226, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +228, +228, +228, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +230, +230, +230, +230, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +233, +233, +233, +233, +234, +234, +234, +234, +234, +234, +234, +234, +234, +234, +234, +235, +235, +235, +235, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +237, +237, +237, +237, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +239, +239, +239, +239, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +241, +241, +241, +241, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +243, +243, +243, +243, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +245, +245, +245, +245, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +247, +247, +247, +247, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +249, +249, +249, +249, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +251, +251, +251, +251, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +254, +254, +254, +254, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255 Index: git/drivers/media/video/isp/cfa_coef_table.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ git/drivers/media/video/isp/cfa_coef_table.h 2009-02-12 10:29:26.000000000 -0600 @@ -0,0 +1,592 @@ +/* + * drivers/media/video/omap/isp/cfa_coef_table.h + * + * CFA Coefficient Table values for TI's OMAP3430 Camera ISP + * + * Copyright (C) 2007 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +0, +0, +248, +0, +0, +40, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +40, +0, +0, +248, +0, +0, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +0, +0, +248, +0, +0, +40, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +40, +0, +0, +248, +0, +0, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +0, +0, +248, +0, +0, +40, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +40, +0, +0, +248, +0, +0, +0, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +0, +0, +40, +0, +0, +0, +0, +248, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +0, +0, +248, +0, +0, +40, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +40, +0, +0, +248, +0, +0, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +0, +0, +248, +0, +0, +40, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +40, +0, +0, +248, +0, +0, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +0, +0, +248, +0, +0, +40, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +40, +0, +0, +248, +0, +0, +0 Index: git/drivers/media/video/isp/greengamma_table.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ git/drivers/media/video/isp/greengamma_table.h 2009-02-12 10:29:26.000000000 -0600 @@ -0,0 +1,1040 @@ +/* + * drivers/media/video/omap/isp/redgamma_table.h + * + * Gamma Table values for Red for TI's OMAP3430 Camera ISP + * + * Copyright (C) 2007 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +0, +0, +1, +2, +3, +3, +4, +5, +6, +8, +10, +12, +14, +16, +18, +20, +22, +23, +25, +26, +28, +29, +31, +32, +34, +35, +36, +37, +39, +40, +41, +42, +43, +44, +45, +46, +47, +48, +49, +50, +51, +52, +52, +53, +54, +55, +56, +57, +58, +59, +60, +61, +62, +63, +63, +64, +65, +66, +66, +67, +68, +69, +69, +70, +71, +72, +72, +73, +74, +75, +75, +76, +77, +78, +78, +79, +80, +81, +81, +82, +83, +84, +84, +85, +86, +87, +88, +88, +89, +90, +91, +91, +92, +93, +94, +94, +95, +96, +97, +97, +98, +98, +99, +99, +100, +100, +101, +101, +102, +103, +104, +104, +105, +106, +107, +108, +108, +109, +110, +111, +111, +112, +113, +114, +114, +115, +116, +117, +117, +118, +119, +119, +120, +120, +121, +121, +122, +122, +123, +123, +124, +124, +125, +125, +126, +126, +127, +127, +128, +128, +129, +129, +130, +130, +131, +131, +132, +132, +133, +133, +134, +134, +135, +135, +136, +136, +137, +137, +138, +138, +139, +139, +140, +140, +141, +141, +142, +142, +143, +143, +144, +144, +145, +145, +146, +146, +147, +147, +148, +148, +149, +149, +150, +150, +151, +151, +152, +152, +153, +153, +153, +153, +154, +154, +154, +154, +155, +155, +156, +156, +157, +157, +158, +158, +158, +159, +159, +159, +160, +160, +160, +161, +161, +162, +162, +163, +163, +164, +164, +164, +164, +165, +165, +165, +165, +166, +166, +167, +167, +168, +168, +169, +169, +170, +170, +170, +170, +171, +171, +171, +171, +172, +172, +173, +173, +174, +174, +175, +175, +176, +176, +176, +176, +177, +177, +177, +177, +178, +178, +178, +178, +179, +179, +179, +179, +180, +180, +180, +180, +181, +181, +181, +181, +182, +182, +182, +182, +183, +183, +183, +183, +184, +184, +184, +184, +185, +185, +185, +185, +186, +186, +186, +186, +187, +187, +187, +187, +188, +188, +188, +188, +189, +189, +189, +189, +190, +190, +190, +190, +191, +191, +191, +191, +192, +192, +192, +192, +193, +193, +193, +193, +194, +194, +194, +194, +195, +195, +195, +195, +196, +196, +196, +196, +197, +197, +197, +197, +198, +198, +198, +198, +199, +199, +199, +199, +200, +200, +200, +200, +201, +201, +201, +201, +202, +202, +202, +203, +203, +203, +203, +204, +204, +204, +204, +205, +205, +205, +205, +206, +206, +206, +206, +207, +207, +207, +207, +208, +208, +208, +208, +209, +209, +209, +209, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +211, +211, +211, +211, +211, +211, +211, +211, +211, +211, +211, +212, +212, +212, +212, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +214, +214, +214, +214, +215, +215, +215, +215, +215, +215, +215, +215, +215, +215, +215, +216, +216, +216, +216, +217, +217, +217, +217, +218, +218, +218, +218, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +220, +220, +220, +220, +221, +221, +221, +221, +221, +221, +221, +221, +221, +221, +221, +222, +222, +222, +222, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +224, +224, +224, +224, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +226, +226, +226, +226, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +228, +228, +228, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +230, +230, +230, +230, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +233, +233, +233, +233, +234, +234, +234, +234, +234, +234, +234, +234, +234, +234, +234, +235, +235, +235, +235, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +237, +237, +237, +237, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +239, +239, +239, +239, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +241, +241, +241, +241, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +243, +243, +243, +243, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +245, +245, +245, +245, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +247, +247, +247, +247, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +249, +249, +249, +249, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +251, +251, +251, +251, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +254, +254, +254, +254, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255 Index: git/drivers/media/video/isp/isp.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ git/drivers/media/video/isp/isp.c 2009-02-12 15:21:14.000000000 -0600 @@ -0,0 +1,2301 @@ +/* + * drivers/media/video/isp/isp.c + * + * Driver Library for ISP Control module in TI's OMAP3430 Camera ISP + * ISP interface and IRQ related APIs are defined here. + * + * Copyright (C) 2008 Texas Instruments. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "isp.h" +#include "ispreg.h" +#include "ispccdc.h" +#include "isppreview.h" +#include "ispresizer.h" +#include "ispmmu.h" +#include "isph3a.h" +#include "isp_af.h" +#include "isphist.h" + +#define ISP_XCLKA_DEFAULT 0x12 + +#ifdef CONFIG_VIDEO_OMAP34XX_ISP_PREVIEWER +#define USE_ISP_PREVIEW +#endif + +#ifdef CONFIG_VIDEO_OMAP34XX_ISP_RESIZER +#define USE_ISP_RESZ +#endif +/* list of image formats supported via OMAP ISP */ +const static struct v4l2_fmtdesc isp_formats[] = { + { +#ifndef ENABLE_BT_656_CAPTURE + .description = "UYVY, packed", +#else + .description = "UYVY (YUV 4:2:2), packed", +#endif + .pixelformat = V4L2_PIX_FMT_UYVY, + }, + { + .description = "YUYV (YUV 4:2:2), packed", + .pixelformat = V4L2_PIX_FMT_YUYV, + }, + { + .description = "Bayer10 (GrR/BGb)", + .pixelformat = V4L2_PIX_FMT_SGRBG10, + }, +}; + +#define NUM_ISP_CAPTURE_FORMATS (sizeof(isp_formats)/sizeof(isp_formats[0])) + + +/* ISP Crop capabilities */ +static struct v4l2_rect ispcroprect; +static struct v4l2_rect cur_rect; + +/* Video controls */ +static struct vcontrol { + struct v4l2_queryctrl qc; + int current_value; +} video_control[] = { + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = ISPPRV_BRIGHT_LOW, + .maximum = ISPPRV_BRIGHT_HIGH, + .step = ISPPRV_BRIGHT_STEP, + .default_value = ISPPRV_BRIGHT_DEF, + }, + .current_value = ISPPRV_BRIGHT_DEF, + }, + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = ISPPRV_CONTRAST_LOW, + .maximum = ISPPRV_CONTRAST_HIGH, + .step = ISPPRV_CONTRAST_STEP, + .default_value = ISPPRV_CONTRAST_DEF, + }, + .current_value = ISPPRV_CONTRAST_DEF, + }, + { + { + .id = V4L2_CID_PRIVATE_ISP_COLOR_FX, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color Effects", + .minimum = PREV_DEFAULT_COLOR, + .maximum = PREV_SEPIA_COLOR, + .step = 1, + .default_value = PREV_DEFAULT_COLOR, + }, + .current_value = PREV_DEFAULT_COLOR, + }, + { + { + .id = V4L2_CID_PRIVATE_ISP_CCDC_CFG, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "CCDC", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .current_value = 0, + }, + { + { + .id = V4L2_CID_PRIVATE_ISP_PRV_CFG, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Previewer", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .current_value = 0, + }, + { + { + .id = V4L2_CID_PRIVATE_ISP_LSC_UPDATE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Tables", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .current_value = 0, + }, + { + { + .id = V4L2_CID_PRIVATE_ISP_AEWB_CFG, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Auto Exposure, Auto WB Config", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .current_value = 0, + }, + { + { + .id = V4L2_CID_PRIVATE_ISP_AEWB_REQ, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "AEWB Request Statistics", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .current_value = 0, + }, + { + { + .id = V4L2_CID_PRIVATE_ISP_AF_CFG, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Auto Focus Config", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .current_value = 0, + }, + { + { + .id = V4L2_CID_PRIVATE_ISP_AF_REQ, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "AF Request Statistics", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .current_value = 0, + } +}; + +/*Structure for IRQ related info */ +static struct ispirq { + isp_callback_t isp_callbk[10]; + isp_vbq_callback_ptr isp_callbk_arg1[10]; + void *isp_callbk_arg2[10]; +} ispirq_obj; + +/* Structure for storing ISP Control module information*/ +static struct isp { + spinlock_t lock; /* spinlock to sync b/w isr and processes */ + spinlock_t isp_temp_buf_lock; + struct mutex isp_mutex; + u8 if_status; + u8 interfacetype; + int ref_count; + struct clk *cam_ick; + struct clk *cam_fck; +} isp_obj; + +struct isp_sgdma ispsg; + +/* Structure for storing ISP sub-module information - CCDC,PRV,RSZ */ +struct ispmodule { + /* Bit mask for sub-modules enabled within the ISP */ + unsigned int isp_pipeline; + int isp_temp_state; + int applyCrop; + struct v4l2_pix_format pix; + /* tried ISP output sizes for video mode */ + unsigned int ccdc_input_width; + unsigned int ccdc_input_height; + unsigned int ccdc_output_width; + unsigned int ccdc_output_height; + unsigned int preview_input_width; + unsigned int preview_input_height; + unsigned int preview_output_width; + unsigned int preview_output_height; + unsigned int resizer_input_width; + unsigned int resizer_input_height; + unsigned int resizer_output_width; + unsigned int resizer_output_height; +#ifdef ENABLE_BT_656_CAPTURE + /* Flag to indicate whether capture is interlaced or progressive */ + int capture_type; + int current_field; + __u32 input_pixelformat; +#endif +}; + +#ifdef ENABLE_BT_656_CAPTURE +#define ISP_SD_STD_PARAMS \ + {"NTSC", 858, 525, 720, 480, 720 * 2, 30, V4L2_PIX_FMT_UYVY, \ + V4L2_FIELD_INTERLACED, 720 * 2, 720 * 2 * 480, \ + V4L2_COLORSPACE_SMPTE170M}, \ + {"PAL", 864, 625, 720, 576, 720 * 2, 25, V4L2_PIX_FMT_UYVY, \ + V4L2_FIELD_INTERLACED, 720 * 2, 720 * 2 * 480, \ + V4L2_COLORSPACE_SMPTE170M} + +struct isp_std_config_params { + char name[30]; + unsigned int num_pixels; + unsigned int num_lines; + unsigned int active_pixels; + unsigned int active_lines; + unsigned int pitch; + unsigned int fps; + __u32 pixelformat; + enum v4l2_field field; + __u32 bytesperline; + __u32 sizeimage; + enum v4l2_colorspace colorspace; +}; + +static struct isp_std_config_params std_params[] = { + ISP_SD_STD_PARAMS +}; +#endif + +static struct ispmodule ispmodule_obj = { + .isp_pipeline = OMAP_ISP_CCDC, + .isp_temp_state = ISP_BUF_INIT, + .applyCrop = 0, + .pix = { + .width = 176, + .height = 144, + .pixelformat = V4L2_PIX_FMT_UYVY, + .field = V4L2_FIELD_NONE, + .bytesperline = 176*2, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0, + }, +#ifdef ENABLE_BT_656_CAPTURE + .capture_type = 0, + .current_field = 0, + .input_pixelformat = V4L2_PIX_FMT_UYVY, +#endif +}; + +/* Structure for saving/restoring ISP module registers*/ + +static struct isp_reg isp_reg_list[] = { + {ISP_SYSCONFIG, 0x0000}, + {ISP_IRQ0ENABLE, 0x0000}, + {ISP_IRQ1ENABLE, 0x0000}, + {ISP_TCTRL_GRESET_LENGTH, 0x0000}, + {ISP_TCTRL_PSTRB_REPLAY, 0x0000}, + {ISP_CTRL, 0x0000}, + {ISP_TCTRL_CTRL, 0x0000}, + {ISP_TCTRL_FRAME, 0x0000}, + {ISP_TCTRL_PSTRB_DELAY, 0x0000}, + {ISP_TCTRL_STRB_DELAY, 0x0000}, + {ISP_TCTRL_SHUT_DELAY, 0x0000}, + {ISP_TCTRL_PSTRB_LENGTH, 0x0000}, + {ISP_TCTRL_STRB_LENGTH, 0x0000}, + {ISP_TCTRL_SHUT_LENGTH, 0x0000}, + {ISP_CBUFF_SYSCONFIG, 0x0000}, + {ISP_CBUFF_IRQENABLE, 0x0000}, + {ISP_CBUFF0_CTRL, 0x0000}, + {ISP_CBUFF1_CTRL, 0x0000}, + {ISP_CBUFF0_START, 0x0000}, + {ISP_CBUFF1_START, 0x0000}, + {ISP_CBUFF0_END, 0x0000}, + {ISP_CBUFF1_END, 0x0000}, + {ISP_CBUFF0_WINDOWSIZE, 0x0000}, + {ISP_CBUFF1_WINDOWSIZE, 0x0000}, + {ISP_CBUFF0_THRESHOLD, 0x0000}, + {ISP_CBUFF1_THRESHOLD, 0x0000}, + {ISP_TOK_TERM, 0x0000} +}; + +/* + * + * V4L2 Handling + * + */ + +/* Returns the index of the requested ID from the control structure array */ +static int +find_vctrl(int id) +{ + int i; + + if (id < V4L2_CID_BASE) + return -EDOM; + + for (i = (ARRAY_SIZE(video_control) - 1); i >= 0; i--) + if (video_control[i].qc.id == id) + break; + if (i < 0) + i = -EINVAL; + return i; +} + +void isp_open(void) +{ + ispccdc_request(); + isppreview_request(); + ispresizer_request(); + return; +} +EXPORT_SYMBOL(isp_open); + +void isp_close(void) +{ + ispccdc_free(); + isppreview_free(); + ispresizer_free(); + memset(&ispcroprect, 0, sizeof(ispcroprect)); + memset(&cur_rect, 0, sizeof(cur_rect)); + return; +} +EXPORT_SYMBOL(isp_close); + +/* flag to check first time of isp_get */ +static int off_mode; + +int isp_set_sgdma_callback(struct isp_sgdma_state *sgdma_state, + isp_vbq_callback_ptr func_ptr) +{ +#ifdef USE_ISP_RESZ + if (ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) { + isp_set_callback(CBK_RESZ_DONE, sgdma_state->callback, + func_ptr, sgdma_state->arg); + } +#endif + +#ifdef USE_ISP_PREVIEW + if (ispmodule_obj.isp_pipeline & OMAP_ISP_PREVIEW) { + isp_set_callback(CBK_PREV_DONE, sgdma_state->callback, + func_ptr, sgdma_state->arg); + } +#endif + if (ispmodule_obj.isp_pipeline & OMAP_ISP_CCDC) { + isp_set_callback(CBK_CCDC_VD0, sgdma_state->callback, func_ptr, + sgdma_state->arg); + isp_set_callback(CBK_CCDC_VD1, sgdma_state->callback, func_ptr, + sgdma_state->arg); +#ifndef ENABLE_BT_656_CAPTURE + isp_set_callback(CBK_LSC_ISR, NULL, NULL, NULL); +#endif + } + isp_set_callback(CBK_HS_VS, sgdma_state->callback, func_ptr, + sgdma_state->arg); + return 0; +} + +/* + *Sets the callback for the ISP module done events. + * type : Type of the event for which callback is requested. + * callback : Method to be called as callback in the ISR context. + * arg1 : Argument to be passed when callback is called in ISR. + * arg2 : Argument to be passed when callback is called in ISR. + */ +int isp_set_callback(enum isp_callback_type type, isp_callback_t callback, + isp_vbq_callback_ptr arg1, + void *arg2) +{ + unsigned long irqflags = 0; + + if (callback == NULL) { + DPRINTK_ISPCTRL("ISP_ERR : Null Callback\n"); + return -EINVAL; + } + + spin_lock_irqsave(&isp_obj.lock, irqflags); + ispirq_obj.isp_callbk[type] = callback; + ispirq_obj.isp_callbk_arg1[type] = arg1; + ispirq_obj.isp_callbk_arg2[type] = arg2; + spin_unlock_irqrestore(&isp_obj.lock, irqflags); + + switch (type) { + case CBK_HS_VS: + omap_writel(IRQ0ENABLE_HS_VS_IRQ, ISP_IRQ0STATUS); + omap_writel(omap_readl(ISP_IRQ0ENABLE) | IRQ0ENABLE_HS_VS_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_PREV_DONE: + omap_writel(IRQ0ENABLE_PRV_DONE_IRQ, ISP_IRQ0STATUS); + omap_writel(omap_readl(ISP_IRQ0ENABLE) | + IRQ0ENABLE_PRV_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_RESZ_DONE: + omap_writel(IRQ0ENABLE_RSZ_DONE_IRQ, ISP_IRQ0STATUS); + omap_writel(omap_readl(ISP_IRQ0ENABLE) | + IRQ0ENABLE_RSZ_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_MMU_ERR: + omap_writel(omap_readl(ISP_IRQ0ENABLE) | + IRQ0ENABLE_MMU_ERR_IRQ, + ISP_IRQ0ENABLE); + + omap_writel(omap_readl(ISPMMU_IRQENABLE) | + IRQENABLE_MULTIHITFAULT | + IRQENABLE_TWFAULT | + IRQENABLE_EMUMISS | + IRQENABLE_TRANSLNFAULT | + IRQENABLE_TLBMISS, + ISPMMU_IRQENABLE); + break; + case CBK_H3A_AWB_DONE: + omap_writel(IRQ0ENABLE_H3A_AWB_DONE_IRQ, ISP_IRQ0STATUS); + omap_writel(omap_readl(ISP_IRQ0ENABLE) | + IRQ0ENABLE_H3A_AWB_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_H3A_AF_DONE: + omap_writel(IRQ0ENABLE_H3A_AF_DONE_IRQ, ISP_IRQ0STATUS); + omap_writel(omap_readl(ISP_IRQ0ENABLE)| + IRQ0ENABLE_H3A_AF_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_HIST_DONE: + omap_writel(IRQ0ENABLE_HIST_DONE_IRQ, ISP_IRQ0STATUS); + omap_writel(omap_readl(ISP_IRQ0ENABLE) | + IRQ0ENABLE_HIST_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_LSC_ISR: + omap_writel(IRQ0ENABLE_CCDC_LSC_DONE_IRQ | + IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ | + IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ, + ISP_IRQ0STATUS); + omap_writel(omap_readl(ISP_IRQ0ENABLE) | + IRQ0ENABLE_CCDC_LSC_DONE_IRQ | + IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ | + IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ, + ISP_IRQ0ENABLE); + break; + default: + break; + }; + + return 0; +} +EXPORT_SYMBOL(isp_set_callback); + +/** + * isp_unset_callback - Clears the callback for the ISP module done events. + * @type: Type of the event for which callback to be cleared. + * + * This function clears a callback function for a done event in the ISP + * module, and disables the corresponding interrupt. + **/ +int isp_unset_callback(enum isp_callback_type type) +{ + unsigned long irqflags = 0; + + spin_lock_irqsave(&isp_obj.lock, irqflags); + ispirq_obj.isp_callbk[type] = NULL; + ispirq_obj.isp_callbk_arg1[type] = NULL; + ispirq_obj.isp_callbk_arg2[type] = NULL; + spin_unlock_irqrestore(&isp_obj.lock, irqflags); + + switch (type) { + case CBK_CCDC_VD0: + omap_writel((omap_readl(ISP_IRQ0ENABLE)) & + ~IRQ0ENABLE_CCDC_VD0_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_CCDC_VD1: + omap_writel((omap_readl(ISP_IRQ0ENABLE)) & + ~IRQ0ENABLE_CCDC_VD1_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_PREV_DONE: + omap_writel((omap_readl(ISP_IRQ0ENABLE)) & + ~IRQ0ENABLE_PRV_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_RESZ_DONE: + omap_writel((omap_readl(ISP_IRQ0ENABLE)) & + ~IRQ0ENABLE_RSZ_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_MMU_ERR: + omap_writel(omap_readl(ISPMMU_IRQENABLE) & + ~(IRQENABLE_MULTIHITFAULT | + IRQENABLE_TWFAULT | + IRQENABLE_EMUMISS | + IRQENABLE_TRANSLNFAULT | + IRQENABLE_TLBMISS), + ISPMMU_IRQENABLE); + break; + case CBK_H3A_AWB_DONE: + omap_writel((omap_readl(ISP_IRQ0ENABLE)) & + ~IRQ0ENABLE_H3A_AWB_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_H3A_AF_DONE: + omap_writel((omap_readl(ISP_IRQ0ENABLE))& + (~IRQ0ENABLE_H3A_AF_DONE_IRQ),ISP_IRQ0ENABLE); + break; + case CBK_HIST_DONE: + omap_writel((omap_readl(ISP_IRQ0ENABLE)) & + ~IRQ0ENABLE_HIST_DONE_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_HS_VS: + omap_writel((omap_readl(ISP_IRQ0ENABLE)) & + ~IRQ0ENABLE_HS_VS_IRQ, + ISP_IRQ0ENABLE); + break; + case CBK_LSC_ISR: + omap_writel(omap_readl(ISP_IRQ0ENABLE) & + ~(IRQ0ENABLE_CCDC_LSC_DONE_IRQ | + IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ | + IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ), + ISP_IRQ0ENABLE); + break; + default: + break; + }; + return 0; +} +EXPORT_SYMBOL(isp_unset_callback); + +/** + * isp_request_interface - Requests an ISP interface type (parallel or serial). + * @if_t: Type of requested ISP interface (parallel or serial). + * + * This function requests for allocation of an ISP interface type. + **/ +int isp_request_interface(enum isp_interface_type if_t) +{ + if (isp_obj.if_status & if_t) { + DPRINTK_ISPCTRL("ISP_ERR : Requested Interface already \ + allocated\n"); + goto err_ebusy; + } + if ((isp_obj.if_status == (ISP_PARLL | ISP_CSIA)) + || isp_obj.if_status == (ISP_CSIA | ISP_CSIB)) { + DPRINTK_ISPCTRL("ISP_ERR : No Free interface now\n"); + goto err_ebusy; + } + + if (((isp_obj.if_status == ISP_PARLL) && (if_t == ISP_CSIA)) || + ((isp_obj.if_status == ISP_CSIA) && + (if_t == ISP_PARLL)) || + ((isp_obj.if_status == ISP_CSIA) && + (if_t == ISP_CSIB)) || + ((isp_obj.if_status == ISP_CSIB) && + (if_t == ISP_CSIA)) || + (isp_obj.if_status == 0)) { + isp_obj.if_status |= if_t; + return 0; + } else { + DPRINTK_ISPCTRL("ISP_ERR : Invalid Combination Serial- \ + Parallel interface\n"); + return -EINVAL; + } + +err_ebusy: + return -EBUSY; +} +EXPORT_SYMBOL(isp_request_interface); + +/** + * isp_free_interface - Frees an ISP interface type (parallel or serial). + * @if_t: Type of ISP interface to be freed (parallel or serial). + * + * This function frees the allocation of an ISP interface type. + **/ +int isp_free_interface(enum isp_interface_type if_t) +{ + isp_obj.if_status &= ~if_t; + return 0; +} +EXPORT_SYMBOL(isp_free_interface); + +/** + * isp_set_xclk - Configures the specified cam_xclk to the desired frequency. + * @xclk: Desired frequency of the clock in Hz. + * @xclksel: XCLK to configure (0 = A, 1 = B). + * + * Configures the specified MCLK divisor in the ISP timing control register + * (TCTRL_CTRL) to generate the desired xclk clock value. + * + * Divisor = CM_CAM_MCLK_HZ / xclk + * + * Returns the final frequency that is actually being generated + **/ +u32 isp_set_xclk(u32 xclk, u8 xclksel) +{ + u32 divisor; + u32 currentxclk; + + if (xclk == CM_CAM_MCLK_HZ) { + divisor = (xclksel == 0) ? ISPTCTRL_CTRL_DIVA_Bypass : + ISPTCTRL_CTRL_DIVB_Bypass; + currentxclk = CM_CAM_MCLK_HZ; + } else { + if (xclk >= 2) { + divisor = CM_CAM_MCLK_HZ / xclk; + divisor &= (xclksel == 0) ? ISPTCTRL_CTRL_DIVA_Bypass : + ISPTCTRL_CTRL_DIVB_Bypass; + currentxclk = CM_CAM_MCLK_HZ / divisor; + } else { + divisor = xclk; + currentxclk = 0; + } + } + + switch (xclksel) { + case 0: + omap_writel((omap_readl(ISP_TCTRL_CTRL) & + ~ISPTCTRL_CTRL_DIVA_Bypass) | + (divisor << ISPTCTRL_CTRL_DIVA_SHIFT), + ISP_TCTRL_CTRL); + DPRINTK_ISPCTRL("isp_set_xclk(): cam_xclka set to %x Hz\n", + currentxclk); + break; + case 1: + omap_writel((omap_readl(ISP_TCTRL_CTRL) & + ~ISPTCTRL_CTRL_DIVB_Bypass) | + (divisor << ISPTCTRL_CTRL_DIVB_SHIFT), + ISP_TCTRL_CTRL); + DPRINTK_ISPCTRL("isp_set_xclk(): cam_xclkb set to %x Hz\n", + currentxclk); + break; + default: + DPRINTK_ISPCTRL("ISP_ERR: isp_set_xclk(): Invalid requested " + "xclk. Must be 0 (A) or 1 (B)." + "\n"); + return -EINVAL; + } + + return currentxclk; +} +EXPORT_SYMBOL(isp_set_xclk); + +/** + * isp_get_xclk - Returns the frequency in Hz of the desired cam_xclk. + * @xclksel: XCLK to retrieve (0 = A, 1 = B). + * + * This function returns the External Clock (XCLKA or XCLKB) value generated + * by the ISP. + **/ +u32 isp_get_xclk(u8 xclksel) +{ + u32 xclkdiv; + u32 xclk; + + switch (xclksel) { + case 0: + xclkdiv = omap_readl(ISP_TCTRL_CTRL) & ISPTCTRL_CTRL_DIVA_MASK; + xclkdiv = xclkdiv >> ISPTCTRL_CTRL_DIVA_SHIFT; + break; + case 1: + xclkdiv = omap_readl(ISP_TCTRL_CTRL) & ISPTCTRL_CTRL_DIVB_MASK; + xclkdiv = xclkdiv >> ISPTCTRL_CTRL_DIVB_SHIFT; + break; + default: + DPRINTK_ISPCTRL("ISP_ERR: isp_get_xclk(): Invalid requested " + "xclk. Must be 0 (A) or 1 (B)." + "\n"); + return -EINVAL; + } + + switch (xclkdiv) { + case 0: + case 1: + xclk = 0; + break; + case 0x1f: + xclk = CM_CAM_MCLK_HZ; + break; + default: + xclk = CM_CAM_MCLK_HZ / xclkdiv; + } + + return xclk; +} +EXPORT_SYMBOL(isp_get_xclk); + +/** + * isp_power_settings - Sysconfig settings, for Power Management. + * @isp_sysconfig: Structure containing the power settings for ISP to configure + * + * Sets the power settings for the ISP, and SBL bus. + **/ +void isp_power_settings(struct isp_sysc isp_sysconfig) +{ + if (isp_sysconfig.idle_mode) { + omap_writel(ISP_SYSCONFIG_AUTOIDLE | + (ISP_SYSCONFIG_MIdleMode_SmartStandBy << + ISP_SYSCONFIG_MIdleMode_SHIFT), + ISP_SYSCONFIG); + + omap_writel(ISPMMU_AUTOIDLE | (ISPMMU_SIdlemode_Smartidle << + ISPMMU_SIdlemode_Shift), + ISPMMU_SYSCONFIG); +/// if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) { + omap_writel(ISPCSI1_AUTOIDLE | + (ISPCSI1_MIdleMode_SmartStandBy << + ISPCSI1_MIdleMode_Shift), + ISP_CSIA_SYSCONFIG); + omap_writel(ISPCSI1_AUTOIDLE | + (ISPCSI1_MIdleMode_SmartStandBy << + ISPCSI1_MIdleMode_Shift), + ISP_CSIB_SYSCONFIG); +/// } + omap_writel(ISPCTRL_SBL_AutoIdle, ISP_CTRL); + + } else { + omap_writel(ISP_SYSCONFIG_AUTOIDLE | + (ISP_SYSCONFIG_MIdleMode_ForceStandBy << + ISP_SYSCONFIG_MIdleMode_SHIFT), ISP_SYSCONFIG); + + omap_writel(ISPMMU_AUTOIDLE | + (ISPMMU_SIdlemode_Noidle << ISPMMU_SIdlemode_Shift), + ISPMMU_SYSCONFIG); +/// if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) { + omap_writel(ISPCSI1_AUTOIDLE | + (ISPCSI1_MIdleMode_ForceStandBy << + ISPCSI1_MIdleMode_Shift), ISP_CSIA_SYSCONFIG); + + omap_writel(ISPCSI1_AUTOIDLE | + (ISPCSI1_MIdleMode_ForceStandBy << + ISPCSI1_MIdleMode_Shift), ISP_CSIB_SYSCONFIG); +/// } + + omap_writel(ISPCTRL_SBL_AutoIdle, ISP_CTRL); + + } + + +} +EXPORT_SYMBOL(isp_power_settings); + +/** + * isp_configure_interface - Configures ISP Control I/F related parameters. + * @config: Structure containing the desired configuration for the ISP. + * + * Configures ISP control register (ISP_CTRL) with the values specified inside + * the config structure. Controls: + * - Selection of parallel or serial input to the preview hardware. + * - Data lane shifter. + * - Pixel clock polarity. + * - 8 to 16-bit bridge at the input of CCDC module. + * - HS or VS synchronization signal detection + **/ +int isp_configure_interface(struct isp_interface_config *config) +{ + u32 ispctrl_val = omap_readl(ISP_CTRL); + u32 ispccdc_vdint_val; + + ispctrl_val &= (ISPCTRL_PAR_SER_CLK_SEL_MASK); + ispctrl_val |= config->ccdc_par_ser; + ispctrl_val &= ISPCTRL_SHIFT_MASK; + ispctrl_val |= (config->dataline_shift << ISPCTRL_SHIFT_SHIFT); + ispctrl_val &= ~ISPCTRL_PAR_CLK_POL_INV; + ispctrl_val |= (config->para_clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT); + ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_BENDIAN; + ispctrl_val |= (config->par_bridge << ISPCTRL_PAR_BRIDGE_SHIFT); + ispctrl_val &= ~(ISPCTRL_SYNC_DETECT_VSRISE); + ispctrl_val |= (config->hsvs_syncdetect << ISPCTRL_SYNC_DETECT_SHIFT); + + omap_writel(ispctrl_val, ISP_CTRL); + + ispccdc_vdint_val = omap_readl(ISPCCDC_VDINT); + ispccdc_vdint_val &= ~(ISPCCDC_VDINT_0_MASK << ISPCCDC_VDINT_0_SHIFT); + ispccdc_vdint_val &= ~(ISPCCDC_VDINT_1_MASK << ISPCCDC_VDINT_1_SHIFT); + omap_writel((config->vdint0_timing << ISPCCDC_VDINT_0_SHIFT) | + (config->vdint1_timing << + ISPCCDC_VDINT_1_SHIFT), + ISPCCDC_VDINT); + return 0; +} +EXPORT_SYMBOL(isp_configure_interface); + +/** + * isp_CCDC_VD01_enable - Enables VD0 and VD1 IRQs. + * + * Sets VD0 and VD1 bits in IRQ0STATUS to reset the flag, and sets them in + * IRQ0ENABLE to enable the corresponding IRQs. + **/ +void isp_CCDC_VD01_enable(void) +{ + omap_writel(IRQ0STATUS_CCDC_VD0_IRQ | IRQ0STATUS_CCDC_VD1_IRQ, + ISP_IRQ0STATUS); + omap_writel(omap_readl(ISP_IRQ0ENABLE) | IRQ0ENABLE_CCDC_VD0_IRQ | + IRQ0ENABLE_CCDC_VD1_IRQ, ISP_IRQ0ENABLE); +} + +/** + * isp_CCDC_VD01_disable - Disables VD0 and VD1 IRQs. + * + * Clears VD0 and VD1 bits in IRQ0ENABLE register. + **/ +void isp_CCDC_VD01_disable(void) +{ + omap_writel(omap_readl(ISP_IRQ0ENABLE) & + ~(IRQ0ENABLE_CCDC_VD0_IRQ | IRQ0ENABLE_CCDC_VD1_IRQ), + ISP_IRQ0ENABLE); +} + +/** + * omap34xx_isp_isr - Interrupt Service Routine for Camera ISP module. + * @irq: Not used currently. + * @ispirq_disp: The object that is passed while request_irq is called. + * This is the ispirq_obj object containing info on the callback. + * + * Handles the corresponding callback if plugged in. + **/ +static irqreturn_t omap34xx_isp_isr(int irq, void *ispirq_disp) +{ + struct ispirq *irqdis = (struct ispirq *) ispirq_disp; + u32 irqstatus = 0; + unsigned long irqflags = 0; + u8 is_irqhandled = 0; + + irqstatus = omap_readl(ISP_IRQ0STATUS); + + spin_lock_irqsave(&isp_obj.lock, irqflags); + + if ((irqstatus & MMU_ERR) == MMU_ERR) { + if (irqdis->isp_callbk[CBK_MMU_ERR]) + irqdis->isp_callbk[CBK_MMU_ERR](irqstatus, + irqdis->isp_callbk_arg1[CBK_MMU_ERR], + irqdis->isp_callbk_arg2[CBK_MMU_ERR]); + is_irqhandled = 1; + goto out; + } + + if ((irqstatus & CCDC_VD1) == CCDC_VD1) { + if (irqdis->isp_callbk[CBK_CCDC_VD1]) + irqdis->isp_callbk[CBK_CCDC_VD1](CCDC_VD1, + irqdis->isp_callbk_arg1[CBK_CCDC_VD1], + irqdis->isp_callbk_arg2[CBK_CCDC_VD1]); + is_irqhandled = 1; + } + + if ((irqstatus & CCDC_VD0) == CCDC_VD0) { + if (irqdis->isp_callbk[CBK_CCDC_VD0]) + irqdis->isp_callbk[CBK_CCDC_VD0](CCDC_VD0, + irqdis->isp_callbk_arg1[CBK_CCDC_VD0], + irqdis->isp_callbk_arg2[CBK_CCDC_VD0]); + is_irqhandled = 1; + } + + if ((irqstatus & PREV_DONE) == PREV_DONE) { + if (irqdis->isp_callbk[CBK_PREV_DONE]) + irqdis->isp_callbk[CBK_PREV_DONE](PREV_DONE, + irqdis->isp_callbk_arg1[CBK_PREV_DONE], + irqdis->isp_callbk_arg2[CBK_PREV_DONE]); + is_irqhandled = 1; + } + + if ((irqstatus & RESZ_DONE) == RESZ_DONE) { + if (irqdis->isp_callbk[CBK_RESZ_DONE]) + irqdis->isp_callbk[CBK_RESZ_DONE](RESZ_DONE, + irqdis->isp_callbk_arg1[CBK_RESZ_DONE], + irqdis->isp_callbk_arg2[CBK_RESZ_DONE]); + is_irqhandled = 1; + } + + if ((irqstatus & H3A_AWB_DONE) == H3A_AWB_DONE) { + if (irqdis->isp_callbk[CBK_H3A_AWB_DONE]) + irqdis->isp_callbk[CBK_H3A_AWB_DONE](H3A_AWB_DONE, + irqdis->isp_callbk_arg1[CBK_H3A_AWB_DONE], + irqdis->isp_callbk_arg2[CBK_H3A_AWB_DONE]); + is_irqhandled = 1; + } + + if ((irqstatus & HIST_DONE) == HIST_DONE) { + if (irqdis->isp_callbk[CBK_HIST_DONE]) + irqdis->isp_callbk[CBK_HIST_DONE](HIST_DONE, + irqdis->isp_callbk_arg1[CBK_HIST_DONE], + irqdis->isp_callbk_arg2[CBK_HIST_DONE]); + is_irqhandled = 1; + } + + if ((irqstatus & HS_VS) == HS_VS) { + if (irqdis->isp_callbk[CBK_HS_VS]) + irqdis->isp_callbk[CBK_HS_VS](HS_VS, + irqdis->isp_callbk_arg1[CBK_HS_VS], + irqdis->isp_callbk_arg2[CBK_HS_VS]); + is_irqhandled = 1; + } + + if ((irqstatus & H3A_AF_DONE) == H3A_AF_DONE){ + if (irqdis->isp_callbk[CBK_H3A_AF_DONE]) + irqdis->isp_callbk[CBK_H3A_AF_DONE](H3A_AF_DONE, + irqdis->isp_callbk_arg1[CBK_H3A_AF_DONE], + irqdis->isp_callbk_arg2[CBK_H3A_AF_DONE]); + is_irqhandled = 1; + } + + if (irqstatus & LSC_PRE_ERR) { + DPRINTK_ISPCTRL("isp_sr: LSC_PRE_ERR \n"); + omap_writel(irqstatus, ISP_IRQ0STATUS); + ispccdc_enable_lsc(0); + ispccdc_enable_lsc(1); + spin_unlock_irqrestore(&isp_obj.lock, irqflags); + return IRQ_HANDLED; + } +out: + omap_writel(irqstatus, ISP_IRQ0STATUS); + spin_unlock_irqrestore(&isp_obj.lock, irqflags); + + if (is_irqhandled) + return IRQ_HANDLED; + else + return IRQ_NONE; +} +#ifdef CONFIG_TRACK_RESOURCES +/* device name needed for resource tracking layer */ +struct device_driver camera_drv = { + .name = "camera" +}; + +struct device camera_dev = { + .driver = &camera_drv, +}; +#endif + +void isp_set_pipeline(int soc_type) +{ + ispmodule_obj.isp_pipeline |= OMAP_ISP_CCDC; + + /* 1- Smart sensor, 0 - Raw sensor */ + if (!soc_type) + ispmodule_obj.isp_pipeline |= (OMAP_ISP_PREVIEW | + OMAP_ISP_RESIZER); + + return; +} + +void +omapisp_unset_callback() +{ + isp_unset_callback(CBK_HS_VS); +#ifdef USE_ISP_RESZ + /* This has to occur before the vysnc of the intended frame comes */ + if (ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) + isp_unset_callback(CBK_RESZ_DONE); +#endif +#ifdef USE_ISP_PREVIEW + if (ispmodule_obj.isp_pipeline & OMAP_ISP_PREVIEW) + isp_unset_callback(CBK_PREV_DONE); +#endif + if (ispmodule_obj.isp_pipeline & OMAP_ISP_CCDC) { + isp_unset_callback(CBK_CCDC_VD0); + isp_unset_callback(CBK_CCDC_VD1); + isp_unset_callback(CBK_LSC_ISR); + } + omap_writel(omap_readl(ISP_IRQ0STATUS) | ISP_INT_CLR, ISP_IRQ0STATUS); +} + +void isp_start(void) +{ + /* start the needed isp components assuming these components + * are configured correctly. + */ +#ifdef USE_ISP_PREVIEW + if (ispmodule_obj.isp_pipeline & OMAP_ISP_PREVIEW) + isppreview_enable(1); +#endif + return ; +} +EXPORT_SYMBOL(isp_start); + +void isp_stop() +{ + int timeout; + + spin_lock(&isp_obj.isp_temp_buf_lock); + ispmodule_obj.isp_temp_state = ISP_FREE_RUNNING; + spin_unlock(&isp_obj.isp_temp_buf_lock); + omapisp_unset_callback(); + +#ifdef USE_ISP_RESZ + if (ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) { + ispresizer_enable(0); + timeout = 0; + while (ispresizer_busy() && (timeout < 20)) { + timeout++; + schedule(); + } + } +#endif +#ifdef USE_ISP_PREVIEW + if (ispmodule_obj.isp_pipeline & OMAP_ISP_PREVIEW) { + isppreview_enable(0); + timeout = 0; + while (isppreview_busy() && (timeout < 20)) { + timeout++; + schedule(); + } + } +#endif + if (ispmodule_obj.isp_pipeline & OMAP_ISP_CCDC) { + ispccdc_enable(0); + timeout = 0; + while (ispccdc_busy() && (timeout < 20)) { + timeout++; + schedule(); + } + } + if (ispccdc_busy() || isppreview_busy() || ispresizer_busy()) { + isp_save_ctx(); + omap_writel(omap_readl(ISP_SYSCONFIG) | + ISP_SYSCONFIG_SOFTRESET, ISP_SYSCONFIG); + timeout = 0; + while ((!(omap_readl(ISP_SYSSTATUS) & 0x1)) && timeout < 40) { + timeout++; + mdelay(1); + } + isp_restore_ctx(); + } +} +EXPORT_SYMBOL(isp_stop); + +void isp_set_buf(struct isp_sgdma_state *sgdma_state) +{ +#ifdef USE_ISP_RESZ + /* This has to occur before the vysnc of the intended frame comes */ + if (ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) { + ispresizer_set_outaddr(sgdma_state->isp_addr); + } else +#endif +#ifdef USE_ISP_PREVIEW + if (ispmodule_obj.isp_pipeline & OMAP_ISP_PREVIEW) { + isppreview_set_outaddr(sgdma_state->isp_addr); + } else +#endif + if (ispmodule_obj.isp_pipeline & OMAP_ISP_CCDC) { + ispccdc_set_outaddr(sgdma_state->isp_addr); + } +} + +void isp_calc_pipeline(struct v4l2_pix_format *pix_input, + struct v4l2_pix_format *pix_output) +{ + + ispmodule_obj.isp_pipeline = OMAP_ISP_CCDC; + +#ifdef ENABLE_BT_656_CAPTURE + if (pix_input->field == V4L2_FIELD_NONE) + ispmodule_obj.capture_type = 0; /* Progressive */ + else + ispmodule_obj.capture_type = 1; /* Interlaced */ + + ispmodule_obj.input_pixelformat = pix_input->pixelformat; +#endif + + if ((pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10) && + (pix_output->pixelformat != V4L2_PIX_FMT_SGRBG10)) { + ispmodule_obj.isp_pipeline |= (OMAP_ISP_PREVIEW | + OMAP_ISP_RESIZER); + ispccdc_config_datapath(CCDC_RAW, CCDC_OTHERS_VP); + isppreview_config_datapath(PRV_RAW_CCDC, + PREVIEW_RSZ); + ispresizer_config_datapath(RSZ_OTFLY_YUV); + } else { + if (pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10) + ispccdc_config_datapath(CCDC_RAW, CCDC_OTHERS_MEM); + else +#ifndef ENABLE_BT_656_CAPTURE + ispccdc_config_datapath(CCDC_YUV_SYNC, CCDC_OTHERS_MEM); +#else + ispccdc_config_datapath(CCDC_YUV_BT, CCDC_OTHERS_MEM); +#endif + } + return; +} + + +void isp_config_pipeline(struct v4l2_pix_format *pix_input, + struct v4l2_pix_format *pix_output) +{ + ispccdc_config_size(ispmodule_obj.ccdc_input_width, + ispmodule_obj.ccdc_input_height, + ispmodule_obj.ccdc_output_width, + ispmodule_obj.ccdc_output_height); + + if (ispmodule_obj.isp_pipeline & OMAP_ISP_PREVIEW) + isppreview_config_size(ispmodule_obj.preview_input_width, + ispmodule_obj.preview_input_height, + ispmodule_obj.preview_output_width, + ispmodule_obj.preview_output_height); + + if (ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) + ispresizer_config_size(ispmodule_obj.resizer_input_width, + ispmodule_obj.resizer_input_height, + ispmodule_obj.resizer_output_width, + ispmodule_obj.resizer_output_height); + +#ifdef ENABLE_BT_656_CAPTURE + if (pix_input->pixelformat == V4L2_PIX_FMT_UYVY) + ispccdc_config_y8pos(Y8POS_ODD); + else if (pix_input->pixelformat == V4L2_PIX_FMT_YUYV) + ispccdc_config_y8pos(Y8POS_EVEN); + + if (((pix_input->pixelformat == V4L2_PIX_FMT_UYVY) && + (pix_output->pixelformat == V4L2_PIX_FMT_UYVY)) || + ((pix_input->pixelformat == V4L2_PIX_FMT_YUYV) && + (pix_output->pixelformat == V4L2_PIX_FMT_YUYV))) + /* input and output formats are in same order */ + ispccdc_config_byteswap(0); + else if (((pix_input->pixelformat == V4L2_PIX_FMT_YUYV) && + (pix_output->pixelformat == V4L2_PIX_FMT_UYVY)) || + ((pix_input->pixelformat == V4L2_PIX_FMT_UYVY) && + (pix_output->pixelformat == V4L2_PIX_FMT_YUYV))) + /* input and output formats are in reverse order */ + ispccdc_config_byteswap(1); + + /* Configure Pitch */ + ispccdc_config_outlineoffset(ispmodule_obj.pix.bytesperline, 0, 0); +#endif + + if (pix_output->pixelformat == V4L2_PIX_FMT_UYVY) { + isppreview_config_ycpos(YCPOS_YCrYCb); +#ifdef USE_ISP_RESZ + ispresizer_config_ycpos(0); +#endif + } else { + isppreview_config_ycpos(YCPOS_CrYCbY); +#ifdef USE_ISP_RESZ + ispresizer_config_ycpos(1); +#endif + } + + return; +} + +/* Callback for interrupt completion*/ +void isp_vbq_done(unsigned long status, isp_vbq_callback_ptr arg1, void *arg2) +{ + struct videobuf_buffer *vb = (struct videobuf_buffer *) arg2; + int notify = 0; + int rval = 0; + unsigned long flags; +#ifdef ENABLE_BT_656_CAPTURE + unsigned long fld_stat = (omap_readl(ISPCCDC_SYN_MODE) >> 15) & 0x1; +#endif + switch (status) { + case CCDC_VD0: +#ifdef ENABLE_BT_656_CAPTURE + if (ispmodule_obj.capture_type) { + spin_lock(&isp_obj.isp_temp_buf_lock); + if (ispmodule_obj.current_field != fld_stat) { + if (fld_stat == 0) + ispmodule_obj.current_field = fld_stat; + + spin_unlock(&isp_obj.isp_temp_buf_lock); + return; + } + spin_unlock(&isp_obj.isp_temp_buf_lock); + + if (fld_stat == 0) { /* Skip even fields */ + return; + } + } +#endif + + ispccdc_config_shadow_registers(); + if ((ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) || + (ispmodule_obj.isp_pipeline & OMAP_ISP_PREVIEW)) + return; + else { + spin_lock(&isp_obj.isp_temp_buf_lock); + if (ispmodule_obj.isp_temp_state != ISP_BUF_INIT) { + spin_unlock(&isp_obj.isp_temp_buf_lock); + return; + + } else { + spin_unlock(&isp_obj.isp_temp_buf_lock); + break; + } + } + break; + case CCDC_VD1: +#ifdef ENABLE_BT_656_CAPTURE + if (ispmodule_obj.capture_type) { + spin_lock(&isp_obj.isp_temp_buf_lock); + if (ispmodule_obj.current_field != fld_stat) { + if (fld_stat == 0) + ispmodule_obj.current_field = fld_stat; + + spin_unlock(&isp_obj.isp_temp_buf_lock); + return; + } + + if (fld_stat == 0) { /* Skip even fields */ + return; + } + + spin_unlock(&isp_obj.isp_temp_buf_lock); + } +#endif + + if ((ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) || + (ispmodule_obj.isp_pipeline & OMAP_ISP_PREVIEW)) + return; + spin_lock(&isp_obj.isp_temp_buf_lock); + if (ispmodule_obj.isp_temp_state == ISP_BUF_INIT) { + spin_unlock(&isp_obj.isp_temp_buf_lock); + ispccdc_enable(0); + return; + } + spin_unlock(&isp_obj.isp_temp_buf_lock); + return; + break; + +#ifdef USE_ISP_PREVIEW + case PREV_DONE: + if (ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) { + if (!ispmodule_obj.applyCrop && + (ispmodule_obj.isp_temp_state == + ISP_BUF_INIT)) + ispresizer_enable(1); + if (ispmodule_obj.applyCrop && !ispresizer_busy()) { + ispresizer_enable(0); + ispresizer_applycrop(); + ispmodule_obj.applyCrop = 0; + } + } + isppreview_config_shadow_registers(); + isph3a_update_wb(); + if (ispmodule_obj.isp_pipeline & OMAP_ISP_RESIZER) + return; + break; +#endif + +#ifdef USE_ISP_RESZ + case RESZ_DONE: + ispresizer_config_shadow_registers(); + spin_lock(&isp_obj.isp_temp_buf_lock); + if (ispmodule_obj.isp_temp_state != ISP_BUF_INIT) { + spin_unlock(&isp_obj.isp_temp_buf_lock); + return; + } + spin_unlock(&isp_obj.isp_temp_buf_lock); + break; +#endif + + case HS_VS: +#ifndef ENABLE_BT_656_CAPTURE + spin_lock(&isp_obj.isp_temp_buf_lock); + if (ispmodule_obj.isp_temp_state == ISP_BUF_TRAN) { + isp_CCDC_VD01_enable(); + ispmodule_obj.isp_temp_state = ISP_BUF_INIT; + } + spin_unlock(&isp_obj.isp_temp_buf_lock); + return; +#else + if (ispmodule_obj.capture_type) { + ispmodule_obj.current_field ^= 1; + spin_lock(&isp_obj.isp_temp_buf_lock); + if ((ispmodule_obj.isp_temp_state == ISP_BUF_TRAN) && + (fld_stat == 1)) { + isp_CCDC_VD01_enable(); + ispmodule_obj.current_field = fld_stat; + ispmodule_obj.isp_temp_state = ISP_BUF_INIT; + } + spin_unlock(&isp_obj.isp_temp_buf_lock); + return; + } else { + spin_lock(&isp_obj.isp_temp_buf_lock); + if (ispmodule_obj.isp_temp_state == ISP_BUF_TRAN) { + isp_CCDC_VD01_enable(); + ispmodule_obj.isp_temp_state = ISP_BUF_INIT; + } + spin_unlock(&isp_obj.isp_temp_buf_lock); + return; + } +#endif + + default: + break; + } + + spin_lock_irqsave(&ispsg.lock, flags); + ispsg.free_sgdma++; + if (ispsg.free_sgdma > NUM_SG_DMA) + ispsg.free_sgdma = NUM_SG_DMA; + spin_unlock_irqrestore(&ispsg.lock, flags); + + rval = arg1(vb); + + if (rval) + isp_sgdma_process(&ispsg, 1, ¬ify, arg1); + + return; +} + +void +isp_sgdma_init() +{ + int sg; + + ispsg.free_sgdma = NUM_SG_DMA; + ispsg.next_sgdma = 0; + for (sg = 0; sg < NUM_SG_DMA; sg++) { + ispsg.sg_state[sg].status = 0; + ispsg.sg_state[sg].callback = NULL; + ispsg.sg_state[sg].arg = NULL; + } +} +EXPORT_SYMBOL(isp_sgdma_init); + +void isp_sgdma_process(struct isp_sgdma *sgdma, int irq, int *dma_notify, + isp_vbq_callback_ptr func_ptr) +{ + struct isp_sgdma_state *sgdma_state; + unsigned long flags; + spin_lock_irqsave(&sgdma->lock, flags); + + /* we can at most start or queue one sgdma */ + if ((NUM_SG_DMA - sgdma->free_sgdma) > 0) { + /* get the next sgdma */ + sgdma_state = sgdma->sg_state + + (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA; + if (!irq) { + if (*dma_notify) { + /* case 1: queue & start. */ + isp_set_sgdma_callback(sgdma_state, func_ptr); + isp_set_buf(sgdma_state); + ispccdc_enable(1); + isp_start(); + *dma_notify = 0; + ispmodule_obj.isp_temp_state = ISP_BUF_TRAN; + } else { + /* + * case 3: only need to queue + * (update buf ptr). + */ + if (ispmodule_obj.isp_temp_state == + ISP_FREE_RUNNING) { + isp_set_sgdma_callback(sgdma_state, + func_ptr); + isp_set_buf(sgdma_state); + /* Non startup case */ + ispccdc_enable(1); + ispmodule_obj.isp_temp_state = + ISP_BUF_TRAN; + } + } + } else { + /* case 3:only need to queue (update buf ptr). */ + isp_set_sgdma_callback(sgdma_state, func_ptr); + isp_set_buf(sgdma_state); + /* Non startup case */ + ispccdc_enable(1); + ispmodule_obj.isp_temp_state = ISP_BUF_INIT; + /* TODO: clear irq. old interrupt can come first. + * OK for preview. + */ + if (*dma_notify) { + isp_start(); + *dma_notify = 0; + } + } + } else { + spin_lock(&isp_obj.isp_temp_buf_lock); + /* Disable VD0 and CCDC here before next VSYNC */ + isp_CCDC_VD01_disable(); + ispmodule_obj.isp_temp_state = ISP_FREE_RUNNING; + spin_unlock(&isp_obj.isp_temp_buf_lock); + } + spin_unlock_irqrestore(&sgdma->lock, flags); + return; +} + +int isp_sgdma_queue(struct videobuf_dmabuf *vdma, struct videobuf_buffer *vb, + int irq, int *dma_notify, + isp_vbq_callback_ptr func_ptr) +{ + unsigned long flags; + struct isp_sgdma_state *sg_state; + const struct scatterlist *sglist = vdma->sglist; + int sglen = vdma->sglen; + + if ((sglen < 0) || ((sglen > 0) & !sglist)) + return -EINVAL; + + spin_lock_irqsave(&ispsg.lock, flags); + + if (!ispsg.free_sgdma) { + spin_unlock_irqrestore(&ispsg.lock, flags); + return -EBUSY; + } + + sg_state = ispsg.sg_state + ispsg.next_sgdma; + sg_state->isp_addr = ispsg.isp_addr_capture[vb->i]; + sg_state->status = 0; + sg_state->callback = isp_vbq_done; + sg_state->arg = vb; + + ispsg.next_sgdma = (ispsg.next_sgdma + 1) % NUM_SG_DMA; + ispsg.free_sgdma--; + + spin_unlock_irqrestore(&ispsg.lock, flags); + + isp_sgdma_process(&ispsg, irq, dma_notify, func_ptr); + + return 0; +} +EXPORT_SYMBOL(isp_sgdma_queue); + +int isp_vbq_prepare(struct videobuf_queue *vbq, struct videobuf_buffer *vb, + enum v4l2_field field) +{ + unsigned int isp_addr; + struct videobuf_dmabuf *vdma; + + int err = 0; + + vdma = videobuf_to_dma(vb); + + /* Map the address to ISP MMU */ + isp_addr = ispmmu_map_sg(vdma->sglist, vdma->sglen); + + if (!isp_addr) + err = -EIO; + else + ispsg.isp_addr_capture[vb->i] = isp_addr; + + return err; +} +EXPORT_SYMBOL(isp_vbq_prepare); + +void isp_vbq_release(struct videobuf_queue *vbq, struct videobuf_buffer *vb) +{ + /* Un-Map the address in ISP MMU */ + ispmmu_unmap(ispsg.isp_addr_capture[vb->i]); + ispsg.isp_addr_capture[vb->i] = (dma_addr_t) NULL; + vb->state = VIDEOBUF_NEEDS_INIT; + return; +} +EXPORT_SYMBOL(isp_vbq_release); + +int isp_queryctrl(struct v4l2_queryctrl *a) +{ + int i; + + i = find_vctrl(a->id); + if (i == -EINVAL) + a->flags = V4L2_CTRL_FLAG_DISABLED; + + if (i < 0) + return -EINVAL; + + *a = video_control[i].qc; + return 0; +} +EXPORT_SYMBOL(isp_queryctrl); + +int isp_g_ctrl(struct v4l2_control *a) +{ + u8 current_value; + int rval = 0; + + switch (a->id) { + case V4L2_CID_BRIGHTNESS: + isppreview_query_brightness(¤t_value); + a->value = current_value / ISPPRV_BRIGHT_UNITS; + break; + case V4L2_CID_CONTRAST: + isppreview_query_contrast(¤t_value); + a->value = current_value / ISPPRV_CONTRAST_UNITS; + break; + case V4L2_CID_PRIVATE_ISP_COLOR_FX: + isppreview_get_color(¤t_value); + a->value = current_value; + break; + case V4L2_CID_PRIVATE_ISP_CCDC_CFG: + a->value = 0; + break; + case V4L2_CID_PRIVATE_ISP_PRV_CFG: + a->value = 0; + break; + case V4L2_CID_PRIVATE_ISP_LSC_UPDATE: + a->value = 0; + break; + case V4L2_CID_PRIVATE_ISP_AEWB_CFG: + a->value = 0; + break; + case V4L2_CID_PRIVATE_ISP_AEWB_REQ: + a->value = 0; + break; + case V4L2_CID_PRIVATE_ISP_AF_CFG: + a->value = 0; + break; + case V4L2_CID_PRIVATE_ISP_AF_REQ: + a->value = 0; + break; + default: + rval = -EINVAL; + break; + } + return rval; +} +EXPORT_SYMBOL(isp_g_ctrl); + +int isp_s_ctrl(struct v4l2_control *a) +{ + int rval = 0; + u8 new_value = a->value; + + switch (a->id) { + case V4L2_CID_BRIGHTNESS: + if (new_value > ISPPRV_BRIGHT_HIGH) + rval = -EINVAL; + else + isppreview_update_brightness(&new_value); + break; + case V4L2_CID_CONTRAST: + if (new_value > ISPPRV_CONTRAST_HIGH) + rval = -EINVAL; + else + isppreview_update_contrast(&new_value); + break; + case V4L2_CID_PRIVATE_ISP_COLOR_FX: + if (new_value > PREV_SEPIA_COLOR) + rval = -EINVAL; + else + isppreview_set_color(&new_value); + break; + case V4L2_CID_PRIVATE_ISP_CCDC_CFG: + omap34xx_isp_ccdc_config((void *)a->value); + break; + case V4L2_CID_PRIVATE_ISP_PRV_CFG: + omap34xx_isp_preview_config((void *)a->value); + break; + case V4L2_CID_PRIVATE_ISP_LSC_UPDATE: + omap34xx_isp_tables_update((void *)a->value); + omap34xx_isp_lsc_update((void *)a->value); + break; + case V4L2_CID_PRIVATE_ISP_AEWB_CFG: + if (!a->value) + rval = -EFAULT; + else { + struct isph3a_aewb_config params; + if (copy_from_user(¶ms, (void *)a->value, + sizeof(params))) { + rval = -EFAULT; + printk(KERN_ERR "Failed copy_from_user\n"); + } else + rval = isph3a_aewb_configure(¶ms); + } + break; + case V4L2_CID_PRIVATE_ISP_AEWB_REQ: + if (!a->value) + rval = -EFAULT; + else { + struct isph3a_aewb_data data; + if (copy_from_user(&data, (void *)a->value, + sizeof(data))) { + rval = -EFAULT; + printk(KERN_ERR "Failed copy_from_user\n"); + break; + } + rval = isph3a_aewb_request_statistics(&data); + if (!rval) + if (copy_to_user((void *)a->value, &data, + sizeof(data))) { + rval = -EFAULT; + printk(KERN_ERR + "Failed copy_to_user\n"); + } + } + break; + case V4L2_CID_PRIVATE_ISP_AF_CFG: + if (!a->value) + rval = -EFAULT; + else { + struct af_configuration params; + + if (copy_from_user(¶ms, (struct af_configuration *)a->value, + sizeof(struct af_configuration))) { + rval = -EFAULT; + printk(KERN_ERR "Failed copy_from_user\n"); + } else + rval = isp_af_configure(¶ms); + } + break; + case V4L2_CID_PRIVATE_ISP_AF_REQ: + if (!a->value) + rval = -EFAULT; + else { + struct isp_af_data data; + if (copy_from_user(&data, (void *) (a->value), + sizeof(data))) { + printk(KERN_ERR "Failed copy_from_user\n"); + return -EFAULT; + } + + if(data.update & LENS_CURRENT_POSITION){ +#if 0 + if(dw9710_af_getfocus(&data.lens_current_position)) +#endif + return -EFAULT; + + if (copy_to_user((void *)a->value, &data, + sizeof(data))) { + rval = -EFAULT; + printk(KERN_ERR + "Failed copy_to_user\n"); + } + } + if(data.update & LENS_DESIRED_POSITION) +#if 0 + if(dw9710_af_setfocus(data.desired_lens_direction)) +#endif + return -EFAULT; + + rval = isp_af_request_statistics(&data); + if (!rval) + if (copy_to_user((void *)a->value, &data, + sizeof(data))) { + rval = -EFAULT; + printk(KERN_ERR + "Failed copy_to_user\n"); + } + } + + break; + case V4L2_CID_PRIVATE_ISP_HIST_CFG: + if (!a->value) + rval = -EFAULT; + else { + struct isp_hist_config params; + if (copy_from_user(¶ms, (struct isp_hist_config *)a->value, + sizeof(struct isp_hist_config))) { + rval = -EFAULT; + printk(KERN_ERR "Failed copy_from_user\n"); + } else + rval = isp_hist_configure(¶ms); + } + break; + + case V4L2_CID_PRIVATE_ISP_HIST_REQ: + if (!a->value) + rval = -EFAULT; + else { + struct isp_hist_data data; + + if (copy_from_user(&data, (struct isp_hist_data *)a->value, + sizeof(struct isp_hist_data))) { + rval = -EFAULT; + printk(KERN_ERR "Failed copy_from_user\n"); + } else + rval = isp_hist_request_statistics(&data); + } + break; + default: + rval = -EINVAL; + break; + } + return rval; +} +EXPORT_SYMBOL(isp_s_ctrl); + +int isp_enum_fmt_cap(struct v4l2_fmtdesc *f) +{ + int index = f->index; + enum v4l2_buf_type type = f->type; + int rval = -EINVAL; +#ifdef ENABLE_BT_656_CAPTURE + int num_formats = NUM_ISP_CAPTURE_FORMATS; + + if (ispmodule_obj.input_pixelformat != V4L2_PIX_FMT_SGRBG10) + num_formats--; +#endif + +#ifndef ENABLE_BT_656_CAPTURE + if (index >= NUM_ISP_CAPTURE_FORMATS) + goto err; +#else + if (index >= num_formats) + goto err; +#endif + + memset(f, 0, sizeof(*f)); + f->index = index; + f->type = type; + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + rval = 0; + break; + default: + goto err; + } + + f->flags = isp_formats[index].flags; + strncpy(f->description, isp_formats[index].description, + sizeof(f->description)); + f->pixelformat = isp_formats[index].pixelformat; +err: + return rval; +} +EXPORT_SYMBOL(isp_enum_fmt_cap); + +void isp_g_fmt_cap(struct v4l2_format *f) +{ + f->fmt.pix = ispmodule_obj.pix; + return; +} +EXPORT_SYMBOL(isp_g_fmt_cap); + +int isp_s_fmt_cap(struct v4l2_pix_format *pix_input, + struct v4l2_pix_format *pix_output) +{ + int crop_scaling_w = 0; + int crop_scaling_h = 0; + int rval; + + /* Call Try Size for the ISP */ + isp_calc_pipeline(pix_input, pix_output); + rval = isp_try_size(pix_input, pix_output); + + if (rval) + goto out; + + rval = isp_try_fmt(pix_input, pix_output); + if (rval) + goto out; + + /* Reset crop settings if needed as image size might have changed */ + if (ispcroprect.width == pix_output->width) { + crop_scaling_w = 0; + } else { + if (ispcroprect.width != 0) + crop_scaling_w = 1; + ispcroprect.left = 0; + ispcroprect.width = pix_output->width; + } + + if (ispcroprect.height == pix_output->height) { + crop_scaling_h = 0; + } else { + if (ispcroprect.height != 0) + crop_scali